我是openCV的新手,因此在过去的3到4天里挣扎,我已经检测到纸张边界,现在我想在角落画出4个圆圈。
我从这段代码中绘制边界
const cv::Point* p = &squares[i][0];
int n = (int)squares[i].size();
polylines(image, &p,&n, 1, true, Scalar(255,255,0), 5, CV_AA);
我是openCV的新手,所以在我看来我有左上角点p-> x和p-> y,但我如何得到其他角落,我也在参数& n中混淆了折线方法,该折线方法如何绘制完整的矩形?
当我使用边界矩形时,它并不完美,它在纸张的一侧留下了一点空间。
非常感谢任何帮助
代码是:
- (cv::Mat)finshWork:(cv::Mat &)image
{
// read in the apple (change path to the file)
Mat img0 =image;// imread("/home/philipp/img/apple.jpg", 1);
Mat img1;
cvtColor(img0, img1, CV_RGB2GRAY);
// apply your filter
Canny(img1, img1, 100, 200);
// find the contours
vector< vector<cv::Point> > contours;
findContours(img1, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
/////for SQUARE CODE
std::vector<std::vector<cv::Point> > squares;
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);
cv::Point newPoint = approx[0];
NSLog(@"x is %d and y is %d",newPoint.x,newPoint.y);
}
}
}
const cv::Point* p = &squares[0][0];
int n = (int)squares[0].size();
NSLog(@"%d",n);
//THIS IS WORKING CODE
polylines(image, &p,&n, 1, true, Scalar(0,0,255), 10, CV_AA);
//polylines(image, &p,&n, 1, true, Scalar(255,255,0), 5, CV_AA);
////////////
}
由于
答案 0 :(得分:18)
参考my original code,它只是检测图像上的方块。
这意味着在应用程序的 main 方法中,您可以编写类似以下伪代码的内容来调用find_squares()
:
Mat image = imread("test.jpg", 1);
// Detect all regions in the image that are similar to a rectangle
vector<vector<Point> > squares;
find_squares(image, squares);
// The largest of them probably represents the paper
vector<Point> largest_square;
find_largest_square(squares, largest_square);
// Print the x,y coordinates of the square
cout << "Point 1: " << largest_square[0] << endl;
cout << "Point 2: " << largest_square[1] << endl;
cout << "Point 3: " << largest_square[2] << endl;
cout << "Point 4: " << largest_square[3] << endl;
这个技巧依赖于下面的find_largest_square()
:
void find_largest_square(const vector<vector<Point> >& squares, vector<Point>& biggest_square)
{
if (!squares.size())
{
// no squares detected
return;
}
int max_width = 0;
int max_height = 0;
int max_square_idx = 0;
const int n_points = 4;
for (size_t i = 0; i < squares.size(); i++)
{
// Convert a set of 4 unordered Points into a meaningful cv::Rect structure.
Rect rectangle = boundingRect(Mat(squares[i]));
// cout << "find_largest_square: #" << i << " rectangle x:" << rectangle.x << " y:" << rectangle.y << " " << rectangle.width << "x" << rectangle.height << endl;
// Store the index position of the biggest square found
if ((rectangle.width >= max_width) && (rectangle.height >= max_height))
{
max_width = rectangle.width;
max_height = rectangle.height;
max_square_idx = i;
}
}
biggest_square = squares[max_square_idx];
}