如題,小弟最近在做有關opencv的程式,是關於找出鏡頭畫面之藍色區域並且計算邊長與旋轉角度,由於有時跳出 vector subscript out of range 這段程式碼,後來發現是因為如果攝像機沒有出現目標設定之藍色區域,此時vector會超出他的範圍,如果我想添加一段判斷式在vector channels; 這邊,判斷當vector範圍超出時返還,則該判別式
該如何寫? 小弟試過幾次結果並不成功,還請各位前輩指教一下,以下放是片段程式碼
int main()
{
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << " Camera Has Been Opened !" << endl;
return -1;
}
Mat frame;
while (1) //儲存WebCam上面之畫面
{
cap >> frame;
imwrite("C:/Navigation/WebCam_Image.jpg", frame);
if (frame.empty())
{
cout << " Error Writing the Image !" << endl;
return -4;
}
line(frame, Point(0, 240), Point(640, 240), Scalar(0, 255, 0), 1, CV_AA);
line(frame, Point(320, 0), Point(320, 480), Scalar(0, 255, 0), 1, CV_AA);
imshow("WebCam", frame);
if (waitKey(1) == 27)
{
break;
}
}
//Blue //留住
Mat srcImg, midImg, dstImg;
srcImg = imread("C:/Navigation/WebCam_Image.jpg"); //C:/Lock Mouse/WebCam_Image.jpg //C:/Navigation/5.png
Mat xianshi = srcImg.clone();
Mat redChannel, greenChannel, blueChannel;
//namedWindow("【Original】", WINDOW_AUTOSIZE);
//imshow("【Original】", srcImg);
//0.灰階
Mat grayImg;
vector<Mat> channels;
split(srcImg, channels);
//cvtColor(srcImg,grayImg,COLOR_BGR2GRAY);
grayImg = channels.at(0); //對藍色區域取灰階圖
redChannel = channels.at(2);
greenChannel = channels.at(1);
blueChannel = channels.at(0);
//namedWindow("【Blue 灰度圖】", WINDOW_AUTOSIZE);
//imshow("【Blue 灰度圖】", grayImg);
//1.均值濾波
blur(grayImg, grayImg, Size(20, 20), Point(-1, -1));
//namedWindow("【均值濾波後】", WINDOW_NORMAL);
//imshow("【均值濾波後】", grayImg);
//2.轉化為二值圖
Mat midImg1 = grayImg.clone();
int rowNumber = midImg1.rows;
int colNumber = midImg1.cols;
for (int i = 0; i < rowNumber; i++) //僅限定天藍色區域
{
uchar* data = midImg1.ptr<uchar>(i); //取第i行的首地址
uchar* redData = redChannel.ptr<uchar>(i);
for (int j = 0; j < colNumber; j++)
{
if (data[j] > BIN_DIV&&redData[j] < BIN_DIV * 2 / 3)
data[j] = 255;
else
data[j] = 0;
}
}
namedWindow("【Blue 二值圖】", WINDOW_AUTOSIZE);
imshow("【Blue 二值圖】", midImg1);
Mat midImg2 = midImg1.clone();
Mat element = getStructuringElement(MORPH_RECT, Size(50, 50));
morphologyEx(midImg1, midImg2, MORPH_CLOSE, element);
namedWindow("【Blue 開運算後】", WINDOW_AUTOSIZE);
imshow("【Blue 開運算後】", midImg2);
//cout << "midImg1.channel=" << midImg1.channels() << endl;
//cout << "mdiImg1.depth" << midImg1.depth() << endl;
//3.查找圖像輪廓
Mat midImg3 = Mat::zeros(midImg2.rows, midImg2.cols, CV_8UC3);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(midImg2, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
for (int index = 0; index >= 0; index = hierarchy[index][0])
{
Scalar color(255, 255, 255);
drawContours(midImg3, contours, index, color, NULL, 8, hierarchy);
}
//namedWindow("【輪廓圖】", WINDOW_NORMAL);
//imshow("【輪廓圖】", midImg3);
Mat midImg4 = midImg3.clone();
//4.創建包圍輪廓的矩形邊界
int cnt = 0;
for (int i = 0; i < contours.size(); i++)
{
//float length, length2, midx, midy, midx2, midy2;
static int length, length2, midx, midy, midx2, midy2;
float ang, m, pixel_area, pixel_length, pixel_length2, dis;
//每個輪廓
vector<Point> points = contours[i];
//對給定的2D點集,尋找最小面積的包圍矩形
RotatedRect box = minAreaRect(Mat(points));
Point2f vertex[4];
box.points(vertex);
//繪製出最小面積的包圍矩形
line(xianshi, vertex[0], vertex[1], Scalar(100, 200, 211), 2, CV_AA);
line(xianshi, vertex[1], vertex[2], Scalar(100, 200, 211), 2, CV_AA);
line(xianshi, vertex[2], vertex[3], Scalar(100, 200, 211), 2, CV_AA);
line(xianshi, vertex[3], vertex[0], Scalar(100, 200, 211), 2, CV_AA);
//cout << " [" << i << "] (" << vertex[i].x << "," << vertex[i].y << ")" << endl; //印出座標
//總共 i 個圖形,共 4 * i 個交點
if (i == 0)
{
for (int i = 0; i < 4; i++)
{
circle(xianshi, Point(vertex[i].x, vertex[i].y), 8, Scalar(0, 255, 0), 1); //綠色實心角點 **
//將 4 * i 個交點儲存
vertexx[i] = vertex[i].x;
vertexy[i] = vertex[i].y;
}
}
else
{
for (int j = 0; j < 4; j++)
{
circle(xianshi, Point(vertex[j].x, vertex[j].y), 8, Scalar(0, 255, 0), 1); //綠色實心角點 **
//將 4*i 個交點儲存
vertexx[j + (i * 4)] = vertex[j].x;
vertexy[j + (i * 4)] = vertex[j].y;
}
}
//計算長度
pixel_length = sqrt((vertex[0].x - vertex[1].x)*(vertex[0].x - vertex[1].x) + (vertex[0].y - vertex[1].y)*(vertex[0].y - vertex[1].y));
midx = abs((vertex[0].x - vertex[1].x) / 2) + vertex[1].x;
midy = abs((vertex[0].y - vertex[1].y) / 2) + vertex[1].y;
pixel_length2 = sqrt((vertex[1].x - vertex[2].x)*(vertex[1].x - vertex[2].x) + (vertex[1].y - vertex[2].y)*(vertex[1].y - vertex[2].y)); //3.625
midx2 = abs((vertex[1].x - vertex[2].x) / 2) + vertex[1].x;
midy2 = abs((vertex[1].y - vertex[2].y) / 2) + vertex[2].y;
//Area
pixel_area = pixel_length * pixel_length2;
//cout << " Pixel_Length = " << pixel_length << " , Pixel_Length2 = " << pixel_length2 << endl;
//cout << (" Pixel_Area ") << i << (" = ") << pixel_area << endl;
mag = (pixel_length + pixel_length2) / (2 * 31);
length = pixel_length / mag;
length2 = pixel_length2 / mag;
sprintf_s(text, "%dmm", length);
putText(xianshi, text, Point(midx, midy), fontFace, fontScale, Scalar(255, 255, 255), thickness, 1); //**
circle(xianshi, Point(midx, midy), 4, Scalar(0, 255, 0), 1); //綠色實心角點 **
sprintf_s(text, "%dmm", length2);
putText(xianshi, text, Point(midx2, midy2), fontFace, fontScale, Scalar(255, 255, 255), thickness, 1); //**
circle(xianshi, Point(midx2, midy2), 4, Scalar(0, 255, 0), 1); //綠色實心角點 **
//Angle
m = (vertex[0].y - vertex[1].y) / (vertex[0].x - vertex[1].x);
ang = atan(m)*(180 / pi);
//cout << ("m = ") << m << endl;
cout << (" Angle ") << i << (" = ") << 90 - ang << endl;
//Distance
dis = (6.15 * 110) / mag;
cout << " Distance = " << dis << " mm" << endl;
//mark
sprintf_s(text, "%d", i);
putText(xianshi, text, Point(midx + 50, midy + 50), fontFace, fontScale, Scalar(255, 255, 255), thickness, 1); //**
//繪製中心的光標
Point s1, l, r, u, d;
s1.x = (vertex[0].x + vertex[2].x) / 2.0;
s1.y = (vertex[0].y + vertex[2].y) / 2.0;
l.x = s1.x - 10;
l.y = s1.y;
r.x = s1.x + 10;
r.y = s1.y;
u.x = s1.x;
u.y = s1.y - 10;
d.x = s1.x;
d.y = s1.y + 10;
line(xianshi, l, r, Scalar(255, 255, 255), 1, CV_AA); //水平
capx = r.x - 10;
navx[i] = capx;
line(xianshi, u, d, Scalar(255, 255, 255), 1, CV_AA); //垂直
capy = d.y - 10;
navy[i] = capy;
cout << (" Object Number = ") << i << (", Mid x = ") << capx << (", Mid y = ") << capy << endl;
cout << endl;
}
for (int i = 0; i < contours.size(); i++)
{
navx[25];
navy[25];
//cout << ("i = ") << i << (", navx = ") << navx[i] << (", navy = ") << navy[i] << endl;
}