//获取下一匹配图
CvPoint getNextMinLoc(IplImage *result, CvPoint minLoc, int maxVaule, int templatW, int templatH)
{
// 先将第一个最小值点附近两倍模板宽度和高度的都设置为最大值防止产生干扰
int startX = minLoc.x - templatW;
int startY = minLoc.y - templatH;
int endX = minLoc.x + templatW;
int endY = minLoc.y + templatH;
if(startX < 0 || startY < 0)
{
startX = 0;
startY = 0;
}
if(endX > result->width - 1 || endY > result->height - 1)
{
endX = result->width - 1;
endY = result->height - 1;
}
int y, x;
for(y = startY; y < endY; y++)
{
for(x = startX; x < endX; x++)
{
cvSetReal2D(result, y, x, maxVaule);
}
}
// 然后得到下一个最小值并且返回
double new_minVaule, new_maxValue;
CvPoint new_minLoc, new_maxLoc;
cvMinMaxLoc(result, &new_minVaule, &new_maxValue, &new_minLoc, &new_maxLoc);
return new_minLoc;
}
//模版匹配
int matchImage(IplImage *src,IplImage *templat,IplImage *img3D,IplImage *src2)
{
//获取原图和模版的宽和高
int srcW, srcH, templatW, templatH, resultH, resultW;
srcW = src->width;
srcH = src->height;
templatW = templat->width;
templatH = templat->height;
if(srcW < templatW || srcH < templatH)
{
cout << "模板不能比原图小" << endl;
return 0;
}
resultW = srcW - templatW + 1;
resultH = srcH - templatH + 1;
IplImage * result = cvCreateImage(cvSize(resultW, resultH), 32, 1); // 匹配方法计算的结果最小值为float
cvMatchTemplate(src, templat, result, CV_TM_SQDIFF);
double minValue, maxValue;
CvPoint minLoc, maxLoc;
cvMinMaxLoc(result, &minValue, &maxValue, &minLoc, &maxLoc);
CvPoint new_minLoc;
// 计算下一个最小值
new_minLoc = getNextMinLoc(result, minLoc, maxValue, templatW, templatH);
cvSetImageROI(img3D,cvRect(new_minLoc.x,new_minLoc.y,templatW,templatH));
cvCopy(img3D,src2);
return 0;
}
int getNotSame(IplImage *img,IplImage *img2,int thred1,int thred2)
{
//IplImage *img=cvLoadImage("9.jpg",1);
//IplImage *img2=cvLoadImage("9.jpg",0);
//
cvNormalize(img2,img2,0,256,CV_MINMAX);
cvNormalize(img,img,0,256,CV_MINMAX);
IplImage *src3=cvCreateImage(cvSize(160,278),img2->depth,3);
IplImage *src1=cvCreateImage(cvSize(160,278),img2->depth,1);
IplImage *img3=cvCreateImage(cvGetSize(img2),img2->depth,1);
cvCopy(img2,img3);
cvSetImageROI(img2,cvRect(480,204,160,278));
cvSetImageROI(img,cvRect(480,204,160,278));
cvCopy(img2,src1);
cvCopy(img,src3);
IplImage *src2=cvCreateImage(cvSize(160,278),img2->depth,1);
IplImage *srct=cvCreateImage(cvSize(160,278),img2->depth,3);
IplImage *out=cvCreateImage(cvSize(160,278),img2->depth,1);
matchImage(img3,src1,img,srct);
cvCvtColor(srct,src2,CV_BGR2GRAY);
cvSmooth(src1,src1,CV_GAUSSIAN,3,3);
cvSmooth(src2,src2,CV_GAUSSIAN,3,3);
for(int i=0;i<src1->height;i++)
for(int j=0;j<src1->width;j++)
{
int temp=((uchar*)(src1->imageData + src1->widthStep*(i)))[j]-((uchar*)(src2->imageData + src2->widthStep*(i)))[j];
if(temp>0 &&temp>thred1)
((uchar*)(out->imageData +out->widthStep*i))[j]=temp+100>255?255:temp+100;
else if(temp<0 &&abs(temp)>thred2)
((uchar*)(out->imageData +out->widthStep*i))[j]=abs(temp)+100>255?255:abs(temp)+100;
else
((uchar*)(out->imageData +out->widthStep*i))[j]=0;
}
//IplImage * out3=cvCreateImage(cvSize(out->width,out->height),IPL_DEPTH_8U,3);
//IplImage * res3=cvCreateImage(cvSize(out->width,out->height),IPL_DEPTH_8U,3);
//cvCvtColor(out,out3,CV_GRAY2BGR);
//cvAdd(src3,out3,res3);
//cvSub(res3,src3,res3);
CvMat *pair=cvCreateMat(out->height,out->width*3,CV_8UC3);
CvMat part;
cvGetCols(pair,&part,0,out->width);
//cvCopy(res3,&part);
cvCvtColor(out,&part,CV_GRAY2BGR);
cvGetCols(pair,&part,out->width,out->width*2);
cvCopy(src3,&part);
cvGetCols(pair,&part,out->width*2,out->width*3);
cvCopy(srct,&part);
cvNamedWindow("result");
cvShowImage("result",pair);
cvWaitKey(0);
cvReleaseImage(&img3);
cvReleaseImage(&img2);
cvReleaseImage(&img3);
cvReleaseImage(&src1);
cvReleaseImage(&src2);
cvReleaseImage(&out);
cvReleaseMat(&pair);
return 0;
}
void CGetDiffDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
ShowWindow(SW_HIDE);
Sleep(1000);
Screen("aa.jpg"); //截屏
IplImage *img=cvLoadImage("aa.jpg",1);
IplImage *img2=cvLoadImage("aa.jpg",0);
UpdateData();
getNotSame(img,img2,m_thread1,m_thread2);
ShowWindow(SW_SHOW);
//CDialogEx::OnOK();
CvPoint getNextMinLoc(IplImage *result, CvPoint minLoc, int maxVaule, int templatW, int templatH)
{
// 先将第一个最小值点附近两倍模板宽度和高度的都设置为最大值防止产生干扰
int startX = minLoc.x - templatW;
int startY = minLoc.y - templatH;
int endX = minLoc.x + templatW;
int endY = minLoc.y + templatH;
if(startX < 0 || startY < 0)
{
startX = 0;
startY = 0;
}
if(endX > result->width - 1 || endY > result->height - 1)
{
endX = result->width - 1;
endY = result->height - 1;
}
int y, x;
for(y = startY; y < endY; y++)
{
for(x = startX; x < endX; x++)
{
cvSetReal2D(result, y, x, maxVaule);
}
}
// 然后得到下一个最小值并且返回
double new_minVaule, new_maxValue;
CvPoint new_minLoc, new_maxLoc;
cvMinMaxLoc(result, &new_minVaule, &new_maxValue, &new_minLoc, &new_maxLoc);
return new_minLoc;
}
//模版匹配
int matchImage(IplImage *src,IplImage *templat,IplImage *img3D,IplImage *src2)
{
//获取原图和模版的宽和高
int srcW, srcH, templatW, templatH, resultH, resultW;
srcW = src->width;
srcH = src->height;
templatW = templat->width;
templatH = templat->height;
if(srcW < templatW || srcH < templatH)
{
cout << "模板不能比原图小" << endl;
return 0;
}
resultW = srcW - templatW + 1;
resultH = srcH - templatH + 1;
IplImage * result = cvCreateImage(cvSize(resultW, resultH), 32, 1); // 匹配方法计算的结果最小值为float
cvMatchTemplate(src, templat, result, CV_TM_SQDIFF);
double minValue, maxValue;
CvPoint minLoc, maxLoc;
cvMinMaxLoc(result, &minValue, &maxValue, &minLoc, &maxLoc);
CvPoint new_minLoc;
// 计算下一个最小值
new_minLoc = getNextMinLoc(result, minLoc, maxValue, templatW, templatH);
cvSetImageROI(img3D,cvRect(new_minLoc.x,new_minLoc.y,templatW,templatH));
cvCopy(img3D,src2);
return 0;
}
int getNotSame(IplImage *img,IplImage *img2,int thred1,int thred2)
{
//IplImage *img=cvLoadImage("9.jpg",1);
//IplImage *img2=cvLoadImage("9.jpg",0);
//
cvNormalize(img2,img2,0,256,CV_MINMAX);
cvNormalize(img,img,0,256,CV_MINMAX);
IplImage *src3=cvCreateImage(cvSize(160,278),img2->depth,3);
IplImage *src1=cvCreateImage(cvSize(160,278),img2->depth,1);
IplImage *img3=cvCreateImage(cvGetSize(img2),img2->depth,1);
cvCopy(img2,img3);
cvSetImageROI(img2,cvRect(480,204,160,278));
cvSetImageROI(img,cvRect(480,204,160,278));
cvCopy(img2,src1);
cvCopy(img,src3);
IplImage *src2=cvCreateImage(cvSize(160,278),img2->depth,1);
IplImage *srct=cvCreateImage(cvSize(160,278),img2->depth,3);
IplImage *out=cvCreateImage(cvSize(160,278),img2->depth,1);
matchImage(img3,src1,img,srct);
cvCvtColor(srct,src2,CV_BGR2GRAY);
cvSmooth(src1,src1,CV_GAUSSIAN,3,3);
cvSmooth(src2,src2,CV_GAUSSIAN,3,3);
for(int i=0;i<src1->height;i++)
for(int j=0;j<src1->width;j++)
{
int temp=((uchar*)(src1->imageData + src1->widthStep*(i)))[j]-((uchar*)(src2->imageData + src2->widthStep*(i)))[j];
if(temp>0 &&temp>thred1)
((uchar*)(out->imageData +out->widthStep*i))[j]=temp+100>255?255:temp+100;
else if(temp<0 &&abs(temp)>thred2)
((uchar*)(out->imageData +out->widthStep*i))[j]=abs(temp)+100>255?255:abs(temp)+100;
else
((uchar*)(out->imageData +out->widthStep*i))[j]=0;
}
//IplImage * out3=cvCreateImage(cvSize(out->width,out->height),IPL_DEPTH_8U,3);
//IplImage * res3=cvCreateImage(cvSize(out->width,out->height),IPL_DEPTH_8U,3);
//cvCvtColor(out,out3,CV_GRAY2BGR);
//cvAdd(src3,out3,res3);
//cvSub(res3,src3,res3);
CvMat *pair=cvCreateMat(out->height,out->width*3,CV_8UC3);
CvMat part;
cvGetCols(pair,&part,0,out->width);
//cvCopy(res3,&part);
cvCvtColor(out,&part,CV_GRAY2BGR);
cvGetCols(pair,&part,out->width,out->width*2);
cvCopy(src3,&part);
cvGetCols(pair,&part,out->width*2,out->width*3);
cvCopy(srct,&part);
cvNamedWindow("result");
cvShowImage("result",pair);
cvWaitKey(0);
cvReleaseImage(&img3);
cvReleaseImage(&img2);
cvReleaseImage(&img3);
cvReleaseImage(&src1);
cvReleaseImage(&src2);
cvReleaseImage(&out);
cvReleaseMat(&pair);
return 0;
}
void CGetDiffDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
ShowWindow(SW_HIDE);
Sleep(1000);
Screen("aa.jpg"); //截屏
IplImage *img=cvLoadImage("aa.jpg",1);
IplImage *img2=cvLoadImage("aa.jpg",0);
UpdateData();
getNotSame(img,img2,m_thread1,m_thread2);
ShowWindow(SW_SHOW);
//CDialogEx::OnOK();
}