一、其中编译库的方式:

   

OPENCV的C语言库 opencv库的常用方法_编译器

直接选择win pack的则是已经编译好的库,而选择sources则是需要使用camke来进行编译对于编译器的库。其中第一种的是适合VS2015以上的编译器,而第二种的是适合VS2013左右的库,其中根据自己的编译器选择适合的库很重要,否则会由于库的版本不对出现很多奇怪的问题。其中一个例子如下:

OPENCV的C语言库 opencv库的常用方法_边缘检测_02

这个使用的工具平台集是(V120)工程然后使用的是VC14的库,然后就出现了上面的错误,后来查询了上面的库是在VS2015里的,如下:

OPENCV的C语言库 opencv库的常用方法_编译器_03

当把使用的库改为VC12后就完美的解决的问题了。


1、OpenCV学习笔记(十二):OpenCV坐标系与row&col的关系 (Mat::at(x,y)和Mat::at(Point(x, y))的区别)

row == heigh == Point.y

col == width == Point.x

Mat::at(Point(x, y)) == Mat::at(y,x)

2、矩形的检测,

 其一般步骤是使用边缘检测出边缘,然后进行多边形逼近,使其变为只有四个点的图像,然后计算每个角度的大小值,最后判断是否为矩形。

其关键代码为:

// 找到所有轮廓并且存储在序列中  
   cvFindContours( gray, storage, &contours, sizeof(CvContour),  
    CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );  
  
   // 遍历找到的每个轮廓contours  
   while( contours )  
   {  
     //用指定精度逼近多边形曲线  
    result = cvApproxPoly( contours, sizeof(CvContour), storage,  
     CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 );  
                    
  
    if( result->total == 4 &&  
     fabs(cvContourArea(result,CV_WHOLE_SEQ)) > 500 &&  
     fabs(cvContourArea(result,CV_WHOLE_SEQ)) < 100000 &&  
     cvCheckContourConvexity(result) )  
    {  
     s = 0;  
  
     for( i = 0; i < 5; i++ )  
     {  
      // find minimum angle between joint edges (maximum of cosine)  
      if( i >= 2 )  
      {  
       t = fabs(angle(  
        (CvPoint*)cvGetSeqElem( result, i ),  
        (CvPoint*)cvGetSeqElem( result, i-2 ),  
        (CvPoint*)cvGetSeqElem( result, i-1 )));  
       s = s > t ? s : t;  
      }  
     }  
  
     // if 余弦值 足够小,可以认定角度为90度直角  
     //cos0.1=83度,能较好的趋近直角  
     if( s < 0.1 )    
      for( i = 0; i < 4; i++ )  
       cvSeqPush( squares,  
       (CvPoint*)cvGetSeqElem( result, i ));  
    }  
  
    // 继续查找下一个轮廓  
    contours = contours->h_next;

cvApproxPoly()函数拟合边缘,使其也只有四个点,然后就是使用opencv的可以任意角度选择的

minAreaRect()函数,其返回的是最小包围矩形,又因为我们的contours本身就是真正边缘的外一层了,如果再使用minAreaRect来寻找边缘的外矩形则会导致,定位的精度比实际的位置大了。其结果如下:

OPENCV的C语言库 opencv库的常用方法_OPENCV的C语言库_04

3、自己的大津算法主要点:

//原图大小是:(cols,rows)=(1920,1080)
	imgROI = dstimg(Rect(left - qiege1, top - qiege1, right - left + qiege2, bottom - top + qiege2));
	imshow("ROI",imgROI);
	//equalizeHist(imgROI, dstimg1);
	IplImage*manageimg = &IplImage(imgROI);
	int gg;   
	gg = imgROI.step[0];  //一行的字节数与IplImage的manageimg->widthstep一样,都是1920,实际感兴趣区域的大小是(142,152)。
	int threvalue = ThreSize((unsigned char*)manageimg->imageData, manageimg->height, manageimg->width, 0, 0, manageimg->width, manageimg->height, 0);


  其中感兴趣区域的withstep--字节是跟原图一样大小的,所以在

manageimg->width 不能使用manageimg->withstep,否则一个是142,一个是1920

4、进行Mat通道值的赋值或取值:

for (size_t c = 0; c < 3; c++) //通道值
		{
			for (size_t r = 0; r < 32; r++) //行
			{
				for (size_t h = 0; h < 32; h++) //列
				{
					src_img.at<cv::Vec3b>(r, h)[c] = buf[c*CIFAR10_IMAGE_AREA + r * 32 + h];  //其中的Mat src_img(32, 32, CV_8UC3);
				}
			}
		}



如果是对于三通道的变量赋值给三通道的时代码为:

Vec3b pix;   //其实三通道的,如果是两通道的话是Vec2b,单通道的话是uchar。
for(int r=0;r<img.rows;r++)
	for(int c=0;c<img.cols;c++)
	{
		pix=src.at<Vec3b>(r,c);
		img.at<Vec3b>(r,c);
	}

其中Vec3b color;对应的是三通道的值其跟Vec3f一样,其与RGB的关系为:

color[0]=255;  //0通道的B分量
color[1]=0;   //1通道的G分量
color[2]=0;  //2通道的R分量


OPENCV的C语言库 opencv库的常用方法_边缘检测_05