https://zhidao.baidu.com/question/552568064.html 这个网页居然说是用美图秀秀弄。好歹是做过图像处理的。决定自己弄。
其实很简单,这是处理之前的图像,带一个红圈圈:
我希望没有那个红圈圈:
其实图像处理算法很简单,循环判断该点是不是红色,通过RGB值的范围和R要比G/B两个都大一定的值来判断是否红色。如果是红色,采用周围邻域的平均值来替代。
代码如下:
1 for (int i=1;i<25;i++) 2 { 3 CString filename; 4 filename.Format("%.2d.jpg",i); 5 IplImage *image1=cvLoadImage(filename,-1); 6 cv::Mat ming1(image1,0); 7 //cvNamedWindow("before",0); 8 //cvShowImage("before",image1); 9 int channle=ming1.channels(); 10 vector<mypoint> dian; 11 for(int jx = 0;jx < ming1.rows;jx++) 12 { 13 // 行定位 14 uchar *data =ming1.ptr<uchar>(jx); // 最终要得到的拼接图 15 for (int iy=0;iy < ming1.cols;iy++) 16 { 17 int va1=data[iy*channle+2]; 18 int va2=data[iy*channle+1]; 19 int va3=data[iy*channle+0]; 20 if ((va1>180&&va2<70&&va3<70)||(va1-va2>50&&va1-va3>50))//红色 21 { 22 dian.clear(); 23 for (int m=-8;m<=8;m++)//y 24 { 25 for (int n=-8; n<=8;n++)//x 26 { 27 if ((jx+m)<0||(jx+m)>ming1.rows||(iy+n)<0||(iy+n)>ming1.cols) 28 { 29 continue; 30 }else 31 { 32 uchar *ndata =ming1.ptr<uchar>(jx+m); 33 mypoint f; 34 int niy=iy+n; 35 f.a=ndata[niy*channle+2]; 36 f.b=ndata[niy*channle+1]; 37 f.c=ndata[niy*channle+0]; 38 if ((f.a>180&&f.b<70&&f.c<70)||(f.a-f.b>50&&f.a-f.c>50))//红色 39 { 40 41 }else 42 { 43 dian.push_back(f); 44 } 45 46 } 47 } 48 }//9gedian 49 mypoint sum; 50 sum.a=0; 51 sum.b=0; 52 sum.c=0; 53 for (int k=0; k<dian.size();k++) 54 { 55 sum.a=sum.a+dian[k].a; 56 sum.b=sum.b+dian[k].b; 57 sum.c=sum.c+dian[k].c; 58 } 59 data[iy*channle+2]=(float)sum.a/(dian.size()*1.0); 60 data[iy*channle+1]=(float)sum.b/(dian.size()*1.0); 61 data[iy*channle+0]=(float)sum.c/(dian.size()*1.0); 62 63 } 64 65 } 66 } 67 68 //cvNamedWindow("after",0); 69 //cvShowImage("after",image1); 70 cvSaveImage(filename,image1); 71 72 73 } 74 75 76 77 78 79 80 81 cvWaitKey(0); 82 system("pause"); 83 return 0;