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);
}
}