大佬教程收集整理的这篇文章主要介绍了OpenCV C ++ / Obj-C:检测一张纸/正方形检测,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
这是反复出现的主题,由于我找不到相关的实现,因此决定接受挑战。
我对OpenCV中存在的squares演示进行了一些修改,下面生成的C ++代码能够检测图像中的纸:
voID find_squares(Mat& image, vector<vector<Point> >& squares)
{
// blur will enhance edge detection
Mat blurred(imagE);
medianBlur(image, blurred, 9);
Mat gray0(blurred.size(), CV_8U), gray;
vector<vector<Point> > contours;
// find squares in every color plane of the image
for (int c = 0; c < 3; c++)
{
int ch[] = {C, 0};
mixChAnnels(&blurred, 1, &gray0, 1, ch, 1);
// try several threshold levels
const int threshold_level = 2;
for (int l = 0; l < threshold_level; L++)
{
// Use CAnny instead of zero threshold level!
// CAnny Helps to catch squares with gradIEnt shading
if (l == 0)
{
CAnny(gray0, gray, 10, 20, 3); //
// Dilate Helps to remove potential holes between edge segments
dilate(gray, gray, Mat(), Point(-1,-1));
}
else
{
gray = gray0 >= (l+1) * 255 / threshold_level;
}
// Find contours and store them in a List
findContours(gray, contours, CV_RETR_List, CV_CHAIN_APPROX_SIMPLE);
// Test contours
vector<Point> approx;
for (size_t i = 0; i < contours.size(); i++)
{
// approximate contour with accuracy proportional
// to the contour perimeter
approxpolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), truE)*0.02, truE);
// Note: absolute value of an area is used because
// area may be positive or negative - in accordance with the
// contour orIEntation
if (approx.size() == 4 &&
fabs(contourArea(Mat(approX))) > 1000 &&
isContourConvex(Mat(approX)))
{
double maxCosine = 0;
for (int j = 2; j < 5; j++)
{
double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
maxCosine = MAX(maxCosine, cosinE);
}
if (maxCosine < 0.3)
squares.push_BACk(approX);
}
}
}
}
}
执行此过程后,纸页将成为以下位置中最大的正方形vector
我在测试应用程序中成功实现了OpenCV平方检测示例,但是现在需要过滤输出,因为它很乱-还是我的代码错误?
我对减少偏斜(如那样)和进一步处理的四个角落很感兴趣……
码:
double angle( cv::Point pt1,cv::Point pt2,cv::Point pt0 ) {
double dx1 = pt1.x - pt0.x;
double dy1 = pt1.y - pt0.y;
double dx2 = pt2.x - pt0.x;
double dy2 = pt2.y - pt0.y;
return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}
- (std::vector<std::vector<cv::Point> >)findSquaresInImage:(cv::Mat)_image
{
std::vector<std::vector<cv::Point> > squares;
cv::Mat pyr,timg,gray0(_image.size(),CV_8U),gray;
int thresh = 50,N = 11;
cv::pyrDown(_image,pyr,cv::Size(_image.cols/2,_image.rows/2));
cv::pyrUp(pyr,_image.size());
std::vector<std::vector<cv::Point> > contours;
for( int c = 0; c < 3; c++ ) {
int ch[] = {C,0};
mixChAnnels(&timg,1,&gray0,ch,1);
for( int l = 0; l < N; l++ ) {
if( l == 0 ) {
cv::CAnny(gray0,gray,thresh,5);
cv::dilate(gray,cv::Mat(),cv::Point(-1,-1));
}
else {
gray = gray0 >= (l+1)*255/N;
}
cv::findContours(gray,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
std::vector<cv::Point> approx;
for( size_t i = 0; i < contours.size(); i++ )
{
cv::approxPolyDP(cv::Mat(contours[i]),approx,arcLength(cv::Mat(contours[i]),truE)*0.02,truE);
if( approx.size() == 4 && fabs(contourArea(cv::Mat(approX))) > 1000 && cv::isContourConvex(cv::Mat(approX))) {
double maxCosine = 0;
for( int j = 2; j < 5; j++ )
{
double cosine = fabs(angle(approx[j%4],approx[j-2],approx[j-1]));
maxCosine = MAX(maxCosine,cosinE);
}
if( maxCosine < 0.3 ) {
squares.push_BACk(approX);
}
}
}
}
}
return squares;
}
编辑17/08/2012:
要在图像上绘制检测到的正方形,请使用以下代码:
cv::Mat debugSquares( std::vector<std::vector<cv::Point> > squares,cv::Mat image )
{
for ( int i = 0; i< squares.size(); i++ ) {
// draw contour
cv::drawContours(image,squares,i,cv::Scalar(255,0),8,std::vector<cv::Vec4i>(),cv::Point());
// draw bounding rect
cv::rect rect = boundingRect(cv::Mat(squares[i]));
cv::rectangle(image,rect.tl(),rect.br(),cv::Scalar(0,255,2,0);
// draw rotated rect
cv::rotatedRect minRect = minAreaRect(cv::Mat(squares[i]));
cv::Point2f rect_points[4];
minRect.points( rect_points );
for ( int j = 0; j < 4; j++ ) {
cv::line( image,rect_points[j],rect_points[(j+1)%4],255),8 ); // blue
}
}
return image;
}
以上是大佬教程为你收集整理的OpenCV C ++ / Obj-C:检测一张纸/正方形检测全部内容,希望文章能够帮你解决OpenCV C ++ / Obj-C:检测一张纸/正方形检测所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。