opencv pixel value operation -- Judging corners (notes)

Posted by adams0423 on Sat, 20 Nov 2021 18:24:04 +0100

c++ opencv pixel value operation - auxiliary document corner judgment

There is a set of corner coordinates of corners of vector < point > type (obtained by fitting the document border and calculating the intersection)
There is also a binary document contour map of Mat type (the document image is obtained by Canny contour extraction + findContours() contour detection function)
Since the corner points are obtained by calculating the intersection point of the straight line after Hough transform, some points are not on the real document corner points. It is necessary to judge which corner points find the right position and which do not.

For this reason, it is temporarily considered to try to calculate by obtaining the pixel value near the corner in the document outline.

The document outline (binarization) is as follows

First, refer to the pixel access method of Mat type image

The code is as follows:

Write the way to obtain 8 * 8 pixels near the corner

//vector<Point> corners;// Corner
//Mat Outlineimg;// Binary graph
Mat PointMat(Size(8, 8), Outlineimg.type());//The 8 * 8 matrix is used to store images near corners

int BeginY = corners[num].y - 4, BeginX = corners[num].x - 4;//Take point start position
int EndY = corners[num].y + 4 , EndX = corners[num].x + 4;//Take point termination bit

for (int i =  BeginY ; i < EndY; i++)
{
	for (int j = BeginX; j < EndX; j++)
	{
		PointMat.at<uchar>(i - BeginY, j - BeginX) = Outlineimg.at<uchar>(i, j);
	}
}
imshow("show PointMat", PointMat);//Print images near corners

The image near the corner displayed is as follows:

Existing problem: if the corner is adjacent to the image boundary, the access to the image pixels may cross the boundary, resulting in program crash

Solution: the offset required to obtain the 8 * 8 pixel image near the corners can be calculated according to the current coordinates of corners and the size of Mat image

The code is as follows

vector<Point> DocScan::CalPixValue(Mat& Outlineimg, vector<Point>& corners)//Calculate the pixel value of corners
{
	Mat PointMat(Size(8, 8), Outlineimg.type());
	vector<Point>  Markcorners;
	for (char num=0;num<corners.size();num++)
	{
		int dx, dy;//Offset
        //---------------Offset calculation-------------
		if (corners[num].x - 0 < 4) {
			dx = 4 - corners[num].x;
		}else if (Outlineimg.cols - corners[num].x < 4) {
			dx = Outlineimg.cols - corners[num].x - 4;
		}else
			dx = 0;

		if (corners[num].y - 0 < 4) {
			dy = 4 - corners[num].y;
		}else if (Outlineimg.rows - corners[num].y < 4) {
			dy = Outlineimg.rows - corners[num].y - 4;
		}else
			dy = 0;

		int BeginY = corners[num].y - 4 + dy, BeginX = corners[num].x - 4 + dx;//Take point start position
		int EndY = corners[num].y + 4 + dy, EndX = corners[num].x + 4 + dx;//Take point termination bit
		//----------------Access pixels near corners-----------------
		int whitenum = 0;
		for (int i = BeginY; i < EndY; i++)
		{
			for (int j = BeginX; j < EndX; j++)
			{
				PointMat.at<uchar>(i - BeginY, j - BeginX) = Outlineimg.at<uchar>(i, j);
				if (Outlineimg.at<uchar>(i, j) == 255)//White pixels found
				{
					++whitenum;
				}
			}
		}
		if (whitenum >= 9)//If the number of white pixels > = 9, it may be corner points (not too accurate, the specific parameters can be modified according to individual needs)
		{
			cout << "got edge,whitenum= " << whitenum << endl;
			Markcorners.push_back(corners[num]);//Place qualified corners into Markcorners
		}
	}
	
	imshow("show PointMat", PointMat);//Print images near corners
	return Markcorners;//Returns the corner that meets the criteria
}

Get the Markcorners returned by the function, and then mark them with a yellow circle on the figure
As shown in the figure below, yellow is the possible corner and red is the wrong corner (the purple red point is the endpoint of the line segment fitted by Hough transform, please ignore). It can be seen that the correct corner can be distinguished in general.

However, corners in this case cannot be detected (number of pixels = 7)

Then, it is impossible to meet the demand simply by using pixel calculation. You can consider using the method of finding lines by Hough transform to calculate the angle between the two lines to judge whether they are corners.

Topics: C++ OpenCV