一、其中编译库的方式:
直接选择win pack的则是已经编译好的库,而选择sources则是需要使用camke来进行编译对于编译器的库。其中第一种的是适合VS2015以上的编译器,而第二种的是适合VS2013左右的库,其中根据自己的编译器选择适合的库很重要,否则会由于库的版本不对出现很多奇怪的问题。其中一个例子如下:
这个使用的工具平台集是(V120)工程然后使用的是VC14的库,然后就出现了上面的错误,后来查询了上面的库是在VS2015里的,如下:
当把使用的库改为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来寻找边缘的外矩形则会导致,定位的精度比实际的位置大了。其结果如下:
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分量