将图像的轮廓保存在vector中用来和后面的图像轮廓位置作比较。
代码块
void CImage_defectDlg::ShowPic(vector img)
{
vectorboundRect2; //记录上次画框位置
for (vector::size_type ix = 0; ix != img.size(); ++ix)
{
if (0 == ix % 2)
continue;
CString ErrorName1; //目标图片1
CString ErrorName2; //目标图片2
CString ErrorNum; //重复缺陷次数
const int ErrorValue = 5; //误差值
int flag = 0; //int型重复缺陷次数
bool flag2 = NULL; //单一窗口显示标志位
Mat srcImage = img[ix].clone();
Mat CannyImg;
Mat grayImage;
cvtColor(srcImage, grayImage, CV_BGR2GRAY);
//滤波
GaussianBlur(grayImage, grayImage, Size(3, 3), 0, 0);
Canny(grayImage, CannyImg, 128, 255, 3);
vector<vector<Point>> contours; //用于保存所有轮廓信息
vector<Vec4i> hierarchy;
//轮廓提取
findContours(CannyImg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
vector<vector<Point>> contours_poly(contours.size());//近似后的轮廓点集g_vContours.size()是g_vContours中有多少数据
vector<Rect>boundRect(contours.size());
for (unsigned int i = 0; i < contours.size(); i++)
{
approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true); //用指定精度逼近多边形曲线
boundRect[i] = boundingRect(Mat(contours_poly[i])); //计算点集的最外面(up-right)矩形边界
}
//画轮廓(思考是不是需要在检测板块显示检测成功的两幅图片)
Mat result = Mat::zeros(srcImage.size(), CV_8UC3);
for (unsigned int i = 0; i < contours.size(); i++)
{
drawContours(result, contours_poly, i, Scalar(0, 0, 255), 1, 8, hierarchy, 0, Point());
rectangle(result, boundRect[i].tl(), boundRect[i].br(), Scalar(255, 0, 0), 1, 8, 0);
}
//检测并显示
if (ix != 0)
{
Mat Temporary_pictures = result.clone();
for (unsigned int i = 0; i < boundRect.size(); i++)
{
for (unsigned int j = 0; j < boundRect2.size(); j++)
{
if (abs(boundRect[i].tl().x - boundRect2[j].tl().x <= ErrorValue)
&& abs(boundRect[i].tl().y - boundRect2[j].tl().y) <= ErrorValue
&& abs(boundRect[i].br().x - boundRect2[j].br().x) <= ErrorValue
&& abs(boundRect[i].br().y - boundRect2[j].br().y) <= ErrorValue)
{
rectangle(Temporary_pictures, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 1, 8, 0);
rectangle(RemImg, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 1, 8, 0);
flag++;
ErrorNum.Format(_T("%d"), flag);
ErrorName1.Format(_T("%d"), ix + 1);
ErrorName2.Format(_T("%d"), ix);
MessageBox(_T("第") + ErrorNum + _T("次缺陷位置相同的图片为第") + ErrorName2 + _T("图与第") + ErrorName1 + _T("图"), NULL, MB_ICONINFORMATION);
Defect_display(Temporary_pictures, RemImg);
flag2 = true;
break;
}
}
}
}
if (!flag2)
{
namedWindow("result");
imshow("result", result);
waitKey(100);
destroyWindow("result");
}
RemImg = result.clone();
boundRect2.assign(boundRect.begin(), boundRect.end());
}
}