opencv3.0 Method for identifying and extracting rectangles in graphics

  • 2020-06-19 11:01:32
  • OfStack

opencv is used to identify rectangles in the image.

The main problem is that the shape inside the rectangle leads to the non-closure of the contour.

1. Gaussian filtering was performed on the input grayscale images
2. Make gray histogram, extract threshold and do 2-value processing
3. Extract the outline of the picture
4. Identify the rectangle in the picture
5. Extract the rectangle in the picture

1. Gaussian filtering was performed on the input grayscale images


  cv::Mat src = cv::imread("F:\\t13.bmp",CV_BGR2GRAY);
  cv::Mat hsv;
  GaussianBlur(src,hsv,cv::Size(5,5),0,0);

2. Make gray histogram, extract threshold and do 2-value processing

Given an image, the background is black, the background color of the rectangle is gray, and some other shapes in the rectangle are white, which can be referred to as:
When the contour is extracted, the outer contour of the rectangle is not closed. Therefore, we need to do the gray histogram of the whole image, find the threshold value, and conduct 2-value

To deal with. If the pixel value (black) is less than the threshold value, set to 0 (pure black); If the pixel value (gray and white) is greater than the threshold value, set

Set to 255 (white)


// Quantize the gray scale to 30 levels 
int gbins = 16; 
int histSize[] = {gbins}; 
  // gray scale varies from 0 to 256 
float granges[] = {0,256}; 
const float* ranges[] = { granges }; 
cv::MatND hist; 
// we compute the histogram from the 0-th and 1-st channels 
int channels[] = {0}; 
 
//calculate hist 
calcHist( &hsv, 1, channels, cv::Mat(), // do not use mask 
      hist, 1, histSize, ranges, 
      true, // the histogram is uniform 
      false ); 
//find the max value of hist 
double maxVal=0; 
minMaxLoc(hist, 0, &maxVal, 0, 0); 
 
int scale = 20; 
cv::Mat histImg; 
histImg.create(500,gbins*scale,CV_8UC3); 
 
//show gray scale of hist image 
for(int g=0;g<gbins;g++){ 
  float binVal = hist.at<float>(g,0); 
  int intensity = cvRound(binVal*255); 
  rectangle( histImg, cv::Point(g*scale,0), 
            cv::Point((g+1)*scale - 1,binVal/maxVal*400), 
            CV_RGB(0,0,0), 
            CV_FILLED ); 
} 
cv::imshow("histImg",histImg); 
 
//threshold processing 
cv::Mat hsvRe; 
threshold( hsv, hsvRe, 64, 255,cv::THRESH_BINARY); 

3. Extract the outline of the picture

In order to recognize the rectangle in the image, the outline of the image needs to be extracted before recognition. After filtering and 2-valued processing, the result of contour extraction is much better than that before extraction.

4. Identify rectangles

The rectangle is identified as follows: the outline identified in the picture is a convex shape, has four top angles, and all the top angles are 90 degrees.


vector<Point> approx; 
 
for (size_t i = 0; i < contours.size(); i++) 
{ 
  approxPolyDP(Mat(contours[i]), approx,  
         arcLength(Mat(contours[i]), true)*0.02, true); 
 
  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); 
  } 
} 

Related articles: