2016-01-14 99 views
0

我有一个图像,我获得了它的二进制图像。我期望一个矩形的边界框,但我没有得到它。这是我的代码:检测OCR中的边界框?

vector<vector<Point>> contours; 
Vec4i hierarchy; 
findContours(binary, contours, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 
/*Mat drawing = Mat::zeros(binary.size(), CV_8UC3); 
for (int i = 0; i < contours.size(); i++) 
{ 
    Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); 
    drawContours(drawing, contours, i, color, 1, 8, hierarchy, 0, Point()); 
} 
imshow("contours", drawing);*/ 

vector<Point> approx, approxRectangle; 
Rect bounding_rect(0, 0, 0, 0); 
double max_area = 0; 
for (int i = 0; i < contours.size(); i++)// xet tung contour 
{ 
    approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true); 

    if (approx.size() == 4 && isContourConvex(Mat(approx))) 
    { 
     Rect box = boundingRect(contours[i]); 
     if (bounding_rect.area() == 0){ 
      bounding_rect = box; 
      approxRectangle = approx; 
     } 
     else{ 
      if (bounding_rect.area() < box.area()){ 
       bounding_rect = box; 
       approxRectangle = approx; 
      } 
     } 
    } 
}` 

这是我的形象:

回答

2

你没有得到想要的结果,因为你正在寻找几乎矩形轮廓,但韩元因为你感兴趣的轮廓不是矩形,所以不起作用。你可以看到(蓝色),其轮廓(在我的二值化图像获得)的近似值:

enter image description here

这说明你,这是不是一个可靠的约束。

您可以轻松地解决这个问题,在这种情况下,计算每个轮廓的边框,并保持最大的(绿色):

enter image description here

代码:

#include <opencv2/opencv.hpp> 
#include <iostream> 
#include <algorithm> 
using namespace std; 
using namespace cv; 

int main() 
{ 
    // Load image 
    Mat3b img = imread("path_to_image"); 

    // Convert to grayscale 
    Mat1b binary; 
    cvtColor(img, binary, COLOR_BGR2GRAY); 

    // Binarize (remove anti-aliasing artifacts) 
    binary = binary > 200; 

    // Find contours 
    vector<vector<Point>> contours; 
    findContours(binary.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0)); 

    // Compute the bounding boxes 
    vector<Rect> boxes; 
    for (int i = 0; i < contours.size(); ++i) 
    { 
     boxes.push_back(boundingRect(contours[i])); 
    } 

    // Find index of largest contours 
    int idx_largest_box = distance(boxes.begin(), max_element(boxes.begin(), boxes.end(), [](const Rect& lhs, const Rect& rhs) { 
     return lhs.area() < rhs.area(); 
    })); 

    // Draw largest box 
    rectangle(img, boxes[idx_largest_box], Scalar(0,255,0)); 

    imshow("Result", img); 
    waitKey(); 

    return 0; 
} 
+0

我试着这条路。但有些情况下,图像是歪斜的。我想检测4个角点并使用它来旋转。你有什么建议吗? –

+0

查找最大的斑点,并使用minAreaRect – Miki

+0

或者简单地将此代码更改为使用RotatedRect而不是Rect,使用minAreaRect更改boundingRect。其余的应该是相同的(除了绘图结果) – Miki