Merge pull request #25807 from spdfghi:4.x

Search in two directions when try to add new quad in addOuterQuad #25807

In ChessBoardDetector::addOuterQuad, previous code try to connect new quad with inner quad, if possible, but only search for one direction. I have made  three test images, one is normal(a.jpg), one lossed an outer quad(b.jpg), and then i flipped it vertically(c.jpg). Only last one fails. I fixed it by check two directions and row/col.

Here is the test code and images:
```
Mat img;
vector<Point2f> corners;
auto size = cv::Size(6, 6);
img = imread("D:/tmp/a.jpg", 0);
std::cout<<cv::findChessboardCorners(img, size, corners)<<"\n";
std::cout << corners.size() << "\n";
img = imread("D:/tmp/b.jpg", 0);
std::cout<<cv::findChessboardCorners(img, size, corners)<<"\n";
std::cout << corners.size() << "\n";
img = imread("D:/tmp/c.jpg", 0);
std::cout<<cv::findChessboardCorners(img, size, corners)<<"\n";
std::cout << corners.size() << "\n";
```
![a](https://github.com/opencv/opencv/assets/92856207/0dc7f5bf-7637-4333-9a9f-ec4ede790027)
a
![b](https://github.com/opencv/opencv/assets/92856207/39793485-ca0c-44c0-b44d-a593d36c1888)
b
![c](https://github.com/opencv/opencv/assets/92856207/2e7789c8-cfa5-438c-9530-2862a8a3741f)
c
This commit is contained in:
武士风度的牛 2024-07-24 20:29:13 +08:00 committed by GitHub
parent 14f9d71dd0
commit 160879c100
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1152,22 +1152,40 @@ int ChessBoardDetector::addOuterQuad(ChessBoardQuad& quad, std::vector<ChessBoar
// have to set exact corner
q.corners[j] = quad.corners[i];
// now find other neighbor and add it, if possible
int next_i = (i + 1) & 3;
int prev_i = (i + 3) & 3; // equal to (j + 1) & 3
ChessBoardQuad* quad_prev = quad.neighbors[prev_i];
if (quad_prev &&
quad_prev->ordered &&
quad_prev->neighbors[i] &&
quad_prev->neighbors[i]->ordered )
// set row and col for next step check
switch (i)
{
ChessBoardQuad* qn = quad_prev->neighbors[i];
q.count = 2;
q.neighbors[prev_i] = qn;
qn->neighbors[next_i] = &q;
qn->count += 1;
// have to set exact corner
q.corners[prev_i] = qn->corners[next_i];
case 0:
q.col = quad.col - 1; q.row = quad.row - 1; break;
case 1:
q.col = quad.col + 1; q.row = quad.row - 1; break;
case 2:
q.col = quad.col + 1; q.row = quad.row - 1; break;
case 3:
q.col = quad.col - 1; q.row = quad.row + 1; break;
}
// now find other neighbor and add it, if possible
for (int k = 1; k <= 3; k += 2)
{
int next_i = (i + k) % 4;
int prev_i = (i + k + 2) % 4;
ChessBoardQuad* quad_prev = quad.neighbors[prev_i];
if (quad_prev &&
quad_prev->ordered &&
quad_prev->neighbors[i] &&
quad_prev->neighbors[i]->ordered &&
std::abs(quad_prev->neighbors[i]->col - q.col) == 1 &&
std::abs(quad_prev->neighbors[i]->row - q.row) == 1)
{
ChessBoardQuad* qn = quad_prev->neighbors[i];
q.count = 2;
q.neighbors[prev_i] = qn;
qn->neighbors[next_i] = &q;
qn->count += 1;
// have to set exact corner
q.corners[prev_i] = qn->corners[next_i];
}
}
}
}