mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge branch 4.x
This commit is contained in:
@@ -186,6 +186,39 @@ class aruco_objdetect_test(NewOpenCVTests):
|
||||
self.assertEqual((1, 4, 2), refine_corners[0].shape)
|
||||
np.testing.assert_array_equal(corners, refine_corners)
|
||||
|
||||
def test_charuco_refine(self):
|
||||
aruco_dict = cv.aruco.getPredefinedDictionary(cv.aruco.DICT_6X6_50)
|
||||
board_size = (3, 4)
|
||||
board = cv.aruco.CharucoBoard(board_size, 1., .7, aruco_dict)
|
||||
aruco_detector = cv.aruco.ArucoDetector(aruco_dict)
|
||||
charuco_detector = cv.aruco.CharucoDetector(board)
|
||||
cell_size = 100
|
||||
image = board.generateImage((cell_size*board_size[0], cell_size*board_size[1]))
|
||||
camera = np.array([[1, 0, 0.5],
|
||||
[0, 1, 0.5],
|
||||
[0, 0, 1]])
|
||||
dist = np.array([0, 0, 0, 0, 0], dtype=np.float32).reshape(1, -1)
|
||||
|
||||
# generate gold corners of the ArUco markers for the test
|
||||
gold_corners = np.array(board.getObjPoints())[:, :, 0:2]*cell_size
|
||||
|
||||
# detect corners
|
||||
markerCorners, markerIds, _ = aruco_detector.detectMarkers(image)
|
||||
|
||||
# test refine
|
||||
rejected = [markerCorners[-1]]
|
||||
markerCorners, markerIds = markerCorners[:-1], markerIds[:-1]
|
||||
markerCorners, markerIds, _, _ = aruco_detector.refineDetectedMarkers(image, board, markerCorners, markerIds,
|
||||
rejected, cameraMatrix=camera, distCoeffs=dist)
|
||||
|
||||
charucoCorners, charucoIds, _, _ = charuco_detector.detectBoard(image, markerCorners=markerCorners,
|
||||
markerIds=markerIds)
|
||||
self.assertEqual(len(charucoIds), 6)
|
||||
self.assertEqual(len(markerIds), 6)
|
||||
|
||||
for i, id in enumerate(markerIds.reshape(-1)):
|
||||
np.testing.assert_allclose(gold_corners[id], markerCorners[i].reshape(4, 2), 0.01, 1.)
|
||||
|
||||
def test_write_read_dictionary(self):
|
||||
try:
|
||||
aruco_dict = cv.aruco.getPredefinedDictionary(cv.aruco.DICT_5X5_50)
|
||||
|
||||
@@ -1000,7 +1000,13 @@ static inline void _projectUndetectedMarkers(const Board &board, InputOutputArra
|
||||
OutputArray undetectedMarkersIds) {
|
||||
Mat rvec, tvec; // first estimate board pose with the current avaible markers
|
||||
Mat objPoints, imgPoints; // object and image points for the solvePnP function
|
||||
board.matchImagePoints(detectedCorners, detectedIds, objPoints, imgPoints);
|
||||
// To refine corners of ArUco markers the function refineDetectedMarkers() find an aruco markers pose from 3D-2D point correspondences.
|
||||
// To find 3D-2D point correspondences uses matchImagePoints().
|
||||
// The method matchImagePoints() works with ArUco corners (in Board/GridBoard cases) or with ChArUco corners (in CharucoBoard case).
|
||||
// To refine corners of ArUco markers we need work with ArUco corners only in all boards.
|
||||
// To call matchImagePoints() with ArUco corners for all boards we need to call matchImagePoints() from base class Board.
|
||||
// The method matchImagePoints() implemented in Pimpl and we need to create temp Board object to call the base method.
|
||||
Board(board.getObjPoints(), board.getDictionary(), board.getIds()).matchImagePoints(detectedCorners, detectedIds, objPoints, imgPoints);
|
||||
if (objPoints.total() < 4ull) // at least one marker from board so rvec and tvec are valid
|
||||
return;
|
||||
solvePnP(objPoints, imgPoints, cameraMatrix, distCoeffs, rvec, tvec);
|
||||
|
||||
@@ -355,6 +355,7 @@ static int _getSelfDistance(const Mat &marker) {
|
||||
|
||||
|
||||
Dictionary extendDictionary(int nMarkers, int markerSize, const Dictionary &baseDictionary, int randomSeed) {
|
||||
CV_Assert(nMarkers > 0);
|
||||
RNG rng((uint64)(randomSeed));
|
||||
|
||||
Dictionary out = Dictionary(Mat(), markerSize);
|
||||
@@ -370,7 +371,7 @@ Dictionary extendDictionary(int nMarkers, int markerSize, const Dictionary &base
|
||||
// if baseDictionary is provided, calculate its intermarker distance
|
||||
if(baseDictionary.bytesList.rows > 0) {
|
||||
CV_Assert(baseDictionary.markerSize == markerSize);
|
||||
out.bytesList = baseDictionary.bytesList.clone();
|
||||
out.bytesList = baseDictionary.bytesList.rowRange(0, min(nMarkers, baseDictionary.bytesList.rows)).clone();
|
||||
|
||||
int minDistance = markerSize * markerSize + 1;
|
||||
for(int i = 0; i < out.bytesList.rows; i++) {
|
||||
|
||||
@@ -68,19 +68,14 @@ static void updatePointsResult(OutputArray points_, const vector<Point2f>& point
|
||||
|
||||
static Point2f intersectionLines(Point2f a1, Point2f a2, Point2f b1, Point2f b2)
|
||||
{
|
||||
// Try to solve a two lines intersection (a1, a2) and (b1, b2) as a system of equations:
|
||||
// a2 + u * (a1 - a2) = b2 + v * (b1 - b2)
|
||||
const float divisor = (a1.x - a2.x) * (b1.y - b2.y) - (a1.y - a2.y) * (b1.x - b2.x);
|
||||
const float eps = 0.001f;
|
||||
if (abs(divisor) < eps)
|
||||
return a2;
|
||||
Point2f result_square_angle(
|
||||
((a1.x * a2.y - a1.y * a2.x) * (b1.x - b2.x) -
|
||||
(b1.x * b2.y - b1.y * b2.x) * (a1.x - a2.x)) /
|
||||
divisor,
|
||||
((a1.x * a2.y - a1.y * a2.x) * (b1.y - b2.y) -
|
||||
(b1.x * b2.y - b1.y * b2.x) * (a1.y - a2.y)) /
|
||||
divisor
|
||||
);
|
||||
return result_square_angle;
|
||||
const float u = ((b2.x - a2.x) * (b1.y - b2.y) + (b1.x - b2.x) * (a2.y - b2.y)) / divisor;
|
||||
return a2 + u * (a1 - a2);
|
||||
}
|
||||
|
||||
// / | b
|
||||
@@ -1254,14 +1249,14 @@ bool QRDecode::computeSidesPoints(const vector<Point> &result_integer_hull)
|
||||
{
|
||||
if (points.front().x > points.back().x)
|
||||
{
|
||||
reverse(points.begin(), points.end());
|
||||
std::reverse(points.begin(), points.end());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (points.front().y > points.back().y)
|
||||
{
|
||||
reverse(points.begin(), points.end());
|
||||
std::reverse(points.begin(), points.end());
|
||||
}
|
||||
}
|
||||
if (points.empty())
|
||||
@@ -1637,7 +1632,7 @@ bool QRDecode::findPatternsVerticesPoints(vector<vector<Point> > &patterns_verti
|
||||
}
|
||||
if ((int)min_angle_pnts_indexes.size() == num_vertices) { break; }
|
||||
}
|
||||
sort(min_angle_pnts_indexes.begin(), min_angle_pnts_indexes.end());
|
||||
std::sort(min_angle_pnts_indexes.begin(), min_angle_pnts_indexes.end());
|
||||
|
||||
vector<Point> contour_vertices_points;
|
||||
|
||||
@@ -1766,11 +1761,11 @@ bool QRDecode::findTempPatternsAddingPoints(vector<std::pair<int, vector<Point>
|
||||
}
|
||||
if (abs(p1.x - p2.x) > abs(p1.y - p2.y))
|
||||
{
|
||||
sort(points.begin(), points.end(), sortPointsByX());
|
||||
std::sort(points.begin(), points.end(), sortPointsByX());
|
||||
}
|
||||
else
|
||||
{
|
||||
sort(points.begin(), points.end(), sortPointsByY());
|
||||
std::sort(points.begin(), points.end(), sortPointsByY());
|
||||
}
|
||||
|
||||
temp_patterns_add_points.push_back(std::pair<int, vector<Point> >(idx_curved_side,points));
|
||||
@@ -1914,11 +1909,11 @@ void QRDecode::completeAndSortSides()
|
||||
Point p2 = it->second.back();
|
||||
if (abs(p1.x - p2.x) > abs(p1.y - p2.y))
|
||||
{
|
||||
sort(it->second.begin(), it->second.end(), sortPointsByX());
|
||||
std::sort(it->second.begin(), it->second.end(), sortPointsByX());
|
||||
}
|
||||
else
|
||||
{
|
||||
sort(it->second.begin(), it->second.end(), sortPointsByY());
|
||||
std::sort(it->second.begin(), it->second.end(), sortPointsByY());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2080,8 +2075,8 @@ bool QRDecode::divideIntoEvenSegments(vector<vector<Point2f> > &segments_points)
|
||||
Point2f segment_start = segments_points[i][j];
|
||||
Point2f segment_end = segments_points[i][j + 1];
|
||||
vector<Point2f>::iterator it_start, it_end, it;
|
||||
it_start = find(spline_lines[i].begin(), spline_lines[i].end(), segment_start);
|
||||
it_end = find(spline_lines[i].begin(), spline_lines[i].end(), segment_end);
|
||||
it_start = std::find(spline_lines[i].begin(), spline_lines[i].end(), segment_start);
|
||||
it_end = std::find(spline_lines[i].begin(), spline_lines[i].end(), segment_end);
|
||||
float max_dist_to_line = 0.0;
|
||||
for (it = it_start; it != it_end; it++)
|
||||
{
|
||||
|
||||
@@ -318,4 +318,12 @@ TEST(CV_ArucoGenerateBoard, regression_1226) {
|
||||
});
|
||||
}
|
||||
|
||||
TEST(CV_ArucoDictionary, extendDictionary) {
|
||||
aruco::Dictionary base_dictionary = aruco::getPredefinedDictionary(aruco::DICT_4X4_250);
|
||||
aruco::Dictionary custom_dictionary = aruco::extendDictionary(150, 4, base_dictionary);
|
||||
|
||||
ASSERT_EQ(custom_dictionary.bytesList.rows, 150);
|
||||
ASSERT_EQ(cv::norm(custom_dictionary.bytesList, base_dictionary.bytesList.rowRange(0, 150)), 0.);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -355,7 +355,7 @@ int CV_DetectorTest::validate( int detectorIdx, vector<vector<Rect> >& objects )
|
||||
map[minIdx] = 1;
|
||||
}
|
||||
}
|
||||
noPair += (int)count_if( map.begin(), map.end(), isZero );
|
||||
noPair += (int)std::count_if( map.begin(), map.end(), isZero );
|
||||
totalNoPair += noPair;
|
||||
|
||||
/*if( noPair > cvRound(valRects.size()*eps.noPair)+1 )
|
||||
|
||||
@@ -264,7 +264,8 @@ TEST(Objdetect_QRCode_Encode_Decode, regression)
|
||||
int true_capacity = establishCapacity(mode, version, cur_capacity);
|
||||
|
||||
std::string input_info = symbol_set;
|
||||
std::random_shuffle(input_info.begin(),input_info.end());
|
||||
std::mt19937 rand_gen {1};
|
||||
std::shuffle(input_info.begin(), input_info.end(), rand_gen);
|
||||
int count = 0;
|
||||
if((int)input_info.length() > true_capacity)
|
||||
{
|
||||
@@ -390,15 +391,8 @@ TEST(Objdetect_QRCode_Encode_Decode_Structured_Append, DISABLED_regression)
|
||||
std::string symbol_set = config["symbols_set"];
|
||||
|
||||
std::string input_info = symbol_set;
|
||||
#if defined CV_CXX11
|
||||
// std::random_shuffle is deprecated since C++11 and removed in C++17.
|
||||
// Use manually constructed RNG with a fixed seed and std::shuffle instead.
|
||||
std::mt19937 rand_gen {1};
|
||||
std::shuffle(input_info.begin(), input_info.end(), rand_gen);
|
||||
#else
|
||||
SeededRandFunctor<1> rand_gen;
|
||||
std::random_shuffle(input_info.begin(), input_info.end(), rand_gen);
|
||||
#endif
|
||||
for (int j = min_stuctures_num; j < max_stuctures_num; j++)
|
||||
{
|
||||
QRCodeEncoder::Params params;
|
||||
|
||||
Reference in New Issue
Block a user