1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2023-07-27 18:38:25 +03:00
151 changed files with 5199 additions and 1111 deletions
@@ -23,6 +23,54 @@ struct CharucoDetector::CharucoDetectorImpl {
arucoDetector(_arucoDetector)
{}
bool checkBoard(InputArrayOfArrays markerCorners, InputArray markerIds, InputArray charucoCorners, InputArray charucoIds) {
vector<Mat> mCorners;
markerCorners.getMatVector(mCorners);
Mat mIds = markerIds.getMat();
Mat chCorners = charucoCorners.getMat();
Mat chIds = charucoIds.getMat();
vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx();
vector<Point2f> distance(board.getNearestMarkerIdx().size(), Point2f(0.f, std::numeric_limits<float>::max()));
// distance[i].x: max distance from the i-th charuco corner to charuco corner-forming markers.
// The two charuco corner-forming markers of i-th charuco corner are defined in getNearestMarkerIdx()[i]
// distance[i].y: min distance from the charuco corner to other markers.
for (size_t i = 0ull; i < chIds.total(); i++) {
int chId = chIds.ptr<int>(0)[i];
Point2f charucoCorner(chCorners.ptr<Point2f>(0)[i]);
for (size_t j = 0ull; j < mIds.total(); j++) {
int idMaker = mIds.ptr<int>(0)[j];
Point2f centerMarker((mCorners[j].ptr<Point2f>(0)[0] + mCorners[j].ptr<Point2f>(0)[1] +
mCorners[j].ptr<Point2f>(0)[2] + mCorners[j].ptr<Point2f>(0)[3]) / 4.f);
float dist = sqrt(normL2Sqr<float>(centerMarker - charucoCorner));
// check distance from the charuco corner to charuco corner-forming markers
if (nearestMarkerIdx[chId][0] == idMaker || nearestMarkerIdx[chId][1] == idMaker) {
int nearestCornerId = nearestMarkerIdx[chId][0] == idMaker ? board.getNearestMarkerCorners()[chId][0] : board.getNearestMarkerCorners()[chId][1];
Point2f nearestCorner = mCorners[j].ptr<Point2f>(0)[nearestCornerId];
float distToNearest = sqrt(normL2Sqr<float>(nearestCorner - charucoCorner));
distance[chId].x = max(distance[chId].x, distToNearest);
// check that nearestCorner is nearest point
{
Point2f mid1 = (mCorners[j].ptr<Point2f>(0)[(nearestCornerId + 1) % 4]+nearestCorner)*0.5f;
Point2f mid2 = (mCorners[j].ptr<Point2f>(0)[(nearestCornerId + 3) % 4]+nearestCorner)*0.5f;
float tmpDist = min(sqrt(normL2Sqr<float>(mid1 - charucoCorner)), sqrt(normL2Sqr<float>(mid2 - charucoCorner)));
if (tmpDist < distToNearest)
return false;
}
}
// check distance from the charuco corner to other markers
else
distance[chId].y = min(distance[chId].y, dist);
}
// if distance from the charuco corner to charuco corner-forming markers more then distance from the charuco corner to other markers,
// then a false board is found.
if (distance[chId].x > 0.f && distance[chId].y < std::numeric_limits<float>::max() && distance[chId].x > distance[chId].y)
return false;
}
return true;
}
/** Calculate the maximum window sizes for corner refinement for each charuco corner based on the distance
* to their closest markers */
vector<Size> getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, InputArray markerIds,
@@ -246,6 +294,31 @@ struct CharucoDetector::CharucoDetectorImpl {
Mat(filteredCharucoIds).copyTo(_filteredCharucoIds);
return (int)_filteredCharucoIds.total();
}
void detectBoard(InputArray image, OutputArray charucoCorners, OutputArray charucoIds,
InputOutputArrayOfArrays markerCorners, InputOutputArray markerIds) {
CV_Assert((markerCorners.empty() && markerIds.empty() && !image.empty()) || (markerCorners.total() == markerIds.total()));
vector<vector<Point2f>> tmpMarkerCorners;
vector<int> tmpMarkerIds;
InputOutputArrayOfArrays _markerCorners = markerCorners.needed() ? markerCorners : tmpMarkerCorners;
InputOutputArray _markerIds = markerIds.needed() ? markerIds : tmpMarkerIds;
if (markerCorners.empty() && markerIds.empty()) {
vector<vector<Point2f> > rejectedMarkers;
arucoDetector.detectMarkers(image, _markerCorners, _markerIds, rejectedMarkers);
if (charucoParameters.tryRefineMarkers)
arucoDetector.refineDetectedMarkers(image, board, _markerCorners, _markerIds, rejectedMarkers);
}
// if camera parameters are avaible, use approximated calibration
if(!charucoParameters.cameraMatrix.empty())
interpolateCornersCharucoApproxCalib(_markerCorners, _markerIds, image, charucoCorners, charucoIds);
// else use local homography
else
interpolateCornersCharucoLocalHom(_markerCorners, _markerIds, image, charucoCorners, charucoIds);
// to return a charuco corner, its closest aruco markers should have been detected
filterCornersWithoutMinMarkers(charucoCorners, charucoIds, _markerIds, charucoCorners, charucoIds);
}
};
CharucoDetector::CharucoDetector(const CharucoBoard &board, const CharucoParameters &charucoParams,
@@ -288,34 +361,15 @@ void CharucoDetector::setRefineParameters(const RefineParameters& refineParamete
void CharucoDetector::detectBoard(InputArray image, OutputArray charucoCorners, OutputArray charucoIds,
InputOutputArrayOfArrays markerCorners, InputOutputArray markerIds) const {
CV_Assert((markerCorners.empty() && markerIds.empty() && !image.empty()) || (markerCorners.total() == markerIds.total()));
vector<vector<Point2f>> tmpMarkerCorners;
vector<int> tmpMarkerIds;
InputOutputArrayOfArrays _markerCorners = markerCorners.needed() ? markerCorners : tmpMarkerCorners;
InputOutputArray _markerIds = markerIds.needed() ? markerIds : tmpMarkerIds;
if (markerCorners.empty() && markerIds.empty()) {
vector<vector<Point2f> > rejectedMarkers;
charucoDetectorImpl->arucoDetector.detectMarkers(image, _markerCorners, _markerIds, rejectedMarkers);
if (charucoDetectorImpl->charucoParameters.tryRefineMarkers)
charucoDetectorImpl->arucoDetector.refineDetectedMarkers(image, charucoDetectorImpl->board, _markerCorners,
_markerIds, rejectedMarkers);
charucoDetectorImpl->detectBoard(image, charucoCorners, charucoIds, markerCorners, markerIds);
if (charucoDetectorImpl->checkBoard(markerCorners, markerIds, charucoCorners, charucoIds) == false) {
charucoCorners.release();
charucoIds.release();
}
// if camera parameters are avaible, use approximated calibration
if(!charucoDetectorImpl->charucoParameters.cameraMatrix.empty())
charucoDetectorImpl->interpolateCornersCharucoApproxCalib(_markerCorners, _markerIds, image, charucoCorners,
charucoIds);
// else use local homography
else
charucoDetectorImpl->interpolateCornersCharucoLocalHom(_markerCorners, _markerIds, image, charucoCorners,
charucoIds);
// to return a charuco corner, its closest aruco markers should have been detected
charucoDetectorImpl->filterCornersWithoutMinMarkers(charucoCorners, charucoIds, _markerIds, charucoCorners,
charucoIds);
}
void CharucoDetector::detectDiamonds(InputArray image, OutputArrayOfArrays _diamondCorners, OutputArray _diamondIds,
InputOutputArrayOfArrays inMarkerCorners, InputOutputArrayOfArrays inMarkerIds) const {
InputOutputArrayOfArrays inMarkerCorners, InputOutputArray inMarkerIds) const {
CV_Assert(getBoard().getChessboardSize() == Size(3, 3));
CV_Assert((inMarkerCorners.empty() && inMarkerIds.empty() && !image.empty()) || (inMarkerCorners.total() == inMarkerIds.total()));
@@ -416,7 +470,7 @@ void CharucoDetector::detectDiamonds(InputArray image, OutputArrayOfArrays _diam
// interpolate the charuco corners of the diamond
vector<Point2f> currentMarkerCorners;
Mat aux;
detectBoard(grey, currentMarkerCorners, aux, currentMarker, currentMarkerId);
charucoDetectorImpl->detectBoard(grey, currentMarkerCorners, aux, currentMarker, currentMarkerId);
// if everything is ok, save the diamond
if(currentMarkerCorners.size() > 0ull) {
@@ -8,11 +8,14 @@
#include "../../precomp.hpp"
#include "super_scale.hpp"
#ifdef HAVE_OPENCV_DNN
#include "opencv2/core.hpp"
#include "opencv2/core/utils/logger.hpp"
namespace cv {
namespace barcode {
#ifdef HAVE_OPENCV_DNN
constexpr static float MAX_SCALE = 4.0f;
int SuperScale::init(const std::string &proto_path, const std::string &model_path)
@@ -71,7 +74,26 @@ int SuperScale::superResolutionScale(const Mat &src, Mat &dst)
}
return 0;
}
#else // HAVE_OPENCV_DNN
int SuperScale::init(const std::string &proto_path, const std::string &model_path)
{
CV_UNUSED(proto_path);
CV_UNUSED(model_path);
return 0;
}
void SuperScale::processImageScale(const Mat &src, Mat &dst, float scale, const bool & isEnabled, int sr_max_size)
{
CV_UNUSED(sr_max_size);
if (isEnabled)
{
CV_LOG_WARNING(NULL, "objdetect/barcode: SuperScaling disabled - OpenCV has been built without DNN support");
}
resize(src, dst, Size(), scale, scale, INTER_CUBIC);
}
#endif // HAVE_OPENCV_DNN
} // namespace barcode
} // namespace cv
#endif // HAVE_OPENCV_DNN
@@ -9,8 +9,8 @@
#define OPENCV_BARCODE_SUPER_SCALE_HPP
#ifdef HAVE_OPENCV_DNN
#include "opencv2/dnn.hpp"
# include "opencv2/dnn.hpp"
#endif
namespace cv {
namespace barcode {
@@ -26,44 +26,16 @@ public:
void processImageScale(const Mat &src, Mat &dst, float scale, const bool &use_sr, int sr_max_size = 160);
#ifdef HAVE_OPENCV_DNN
private:
dnn::Net srnet_;
bool net_loaded_ = false;
int superResolutionScale(const cv::Mat &src, cv::Mat &dst);
#endif
};
} // namespace barcode
} // namespace cv
#else // HAVE_OPENCV_DNN
#include "opencv2/core.hpp"
#include "opencv2/core/utils/logger.hpp"
namespace cv {
namespace barcode {
class SuperScale
{
public:
int init(const std::string &, const std::string &)
{
return 0;
}
void processImageScale(const Mat &src, Mat &dst, float scale, const bool & isEnabled, int)
{
if (isEnabled)
{
CV_LOG_WARNING(NULL, "objdetect/barcode: SuperScaling disabled - OpenCV has been built without DNN support");
}
resize(src, dst, Size(), scale, scale, INTER_CUBIC);
}
};
} // namespace barcode
} // namespace cv
#endif // !HAVE_OPENCV_DNN
} // namespace barcode
} // namespace cv
#endif // OPENCV_BARCODE_SUPER_SCALE_HPP