mirror of
https://github.com/opencv/opencv.git
synced 2026-07-28 23:03:03 +04:00
Merge pull request #22025 from AleksandrPanov:fix_samplingForVersion_multiplyingFactor
Fix sampling for version multiplying factor * reduce experimentalFrequencyElem and listFrequencyElem * fix large resize * fix tile in postIntermediate * add getMinSideLen(), add corrected_index * add test decode_regression_21929 author Kumataro, add test decode_regression_version_25
This commit is contained in:
@@ -1070,6 +1070,15 @@ protected:
|
||||
};
|
||||
};
|
||||
|
||||
float static getMinSideLen(const vector<Point2f> &points) {
|
||||
CV_Assert(points.size() == 4ull);
|
||||
double res = norm(points[1]-points[0]);
|
||||
for (size_t i = 1ull; i < points.size(); i++) {
|
||||
res = min(res, norm(points[i]-points[(i+1ull) % points.size()]));
|
||||
}
|
||||
return static_cast<float>(res);
|
||||
}
|
||||
|
||||
void QRDecode::init(const Mat &src, const vector<Point2f> &points)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
@@ -1081,7 +1090,7 @@ void QRDecode::init(const Mat &src, const vector<Point2f> &points)
|
||||
original_points = bbox;
|
||||
version = 0;
|
||||
version_size = 0;
|
||||
test_perspective_size = 251;
|
||||
test_perspective_size = max(getMinSideLen(points)+1.f, 251.f);
|
||||
result_info = "";
|
||||
}
|
||||
|
||||
@@ -2096,7 +2105,7 @@ bool QRDecode::straightenQRCodeInParts()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
float perspective_curved_size = 251.0;
|
||||
float perspective_curved_size = max(getMinSideLen(original_points)+1.f, 251.f);;
|
||||
const Size temporary_size(cvRound(perspective_curved_size), cvRound(perspective_curved_size));
|
||||
|
||||
float dist = perspective_curved_size / (number_pnts_to_cut - 1);
|
||||
@@ -2367,9 +2376,9 @@ bool QRDecode::versionDefinition()
|
||||
bool QRDecode::samplingForVersion()
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
const double multiplyingFactor = (version < 3) ? 1 :
|
||||
(version == 3) ? 1.5 :
|
||||
version * (version + 1);
|
||||
const double multiplyingFactor = (version < 3) ? 1. :
|
||||
(version == 3) ? 2. :
|
||||
3.;
|
||||
const Size newFactorSize(
|
||||
cvRound(no_border_intermediate.size().width * multiplyingFactor),
|
||||
cvRound(no_border_intermediate.size().height * multiplyingFactor));
|
||||
@@ -2378,45 +2387,38 @@ bool QRDecode::samplingForVersion()
|
||||
|
||||
const int delta_rows = cvRound((postIntermediate.rows * 1.0) / version_size);
|
||||
const int delta_cols = cvRound((postIntermediate.cols * 1.0) / version_size);
|
||||
// number of elements in the tail
|
||||
const int skipped_rows = postIntermediate.rows - delta_rows * version_size;
|
||||
const int skipped_cols = postIntermediate.cols - delta_cols * version_size;
|
||||
|
||||
vector<double> listFrequencyElem;
|
||||
for (int r = 0; r < postIntermediate.rows; r += delta_rows)
|
||||
{
|
||||
for (int c = 0; c < postIntermediate.cols; c += delta_cols)
|
||||
{
|
||||
vector<int> deltas_rows(version_size, delta_rows);
|
||||
vector<int> deltas_cols(version_size, delta_cols);
|
||||
|
||||
for (int i = 0; i < abs(skipped_rows); i++) {
|
||||
// fix deltas_rows at each skip_step
|
||||
const double skip_step = static_cast<double>(version_size)/abs(skipped_rows);
|
||||
const int corrected_index = static_cast<int>(i*skip_step + skip_step/2);
|
||||
deltas_rows[corrected_index] += skipped_rows > 0 ? 1 : -1;
|
||||
}
|
||||
for (int i = 0; i < abs(skipped_cols); i++) {
|
||||
// fix deltas_cols at each skip_step
|
||||
const double skip_step = static_cast<double>(version_size)/abs(skipped_cols);
|
||||
const int corrected_index = static_cast<int>(i*skip_step + skip_step/2);
|
||||
deltas_cols[corrected_index] += skipped_cols > 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
const double totalFrequencyElem = countNonZero(postIntermediate) / static_cast<double>(postIntermediate.total());
|
||||
straight = Mat(Size(version_size, version_size), CV_8UC1, Scalar(0));
|
||||
|
||||
for (int r = 0, i = 0; i < version_size; r += deltas_rows[i], i++) {
|
||||
for (int c = 0, j = 0; j < version_size; c += deltas_cols[j], j++) {
|
||||
Mat tile = postIntermediate(
|
||||
Range(r, min(r + delta_rows, postIntermediate.rows)),
|
||||
Range(c, min(c + delta_cols, postIntermediate.cols)));
|
||||
const double frequencyElem = (countNonZero(tile) * 1.0) / tile.total();
|
||||
listFrequencyElem.push_back(frequencyElem);
|
||||
straight.ptr<uint8_t>(i)[j] = (frequencyElem < totalFrequencyElem) ? 0 : 255;
|
||||
}
|
||||
}
|
||||
|
||||
double dispersionEFE = std::numeric_limits<double>::max();
|
||||
double experimentalFrequencyElem = 0;
|
||||
for (double expVal = 0; expVal < 1; expVal+=0.001)
|
||||
{
|
||||
double testDispersionEFE = 0.0;
|
||||
for (size_t i = 0; i < listFrequencyElem.size(); i++)
|
||||
{
|
||||
testDispersionEFE += (listFrequencyElem[i] - expVal) *
|
||||
(listFrequencyElem[i] - expVal);
|
||||
}
|
||||
testDispersionEFE /= (listFrequencyElem.size() - 1);
|
||||
if (dispersionEFE > testDispersionEFE)
|
||||
{
|
||||
dispersionEFE = testDispersionEFE;
|
||||
experimentalFrequencyElem = expVal;
|
||||
}
|
||||
}
|
||||
|
||||
straight = Mat(Size(version_size, version_size), CV_8UC1, Scalar(0));
|
||||
for (int r = 0; r < version_size * version_size; r++)
|
||||
{
|
||||
int i = r / straight.cols;
|
||||
int j = r % straight.cols;
|
||||
straight.ptr<uint8_t>(i)[j] = (listFrequencyElem[r] < experimentalFrequencyElem) ? 0 : 255;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user