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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user