mirror of
https://github.com/opencv/opencv.git
synced 2025-06-12 12:22:51 +08:00
add intro to params
This commit is contained in:
parent
b77047fc08
commit
e548e59cd5
@ -863,10 +863,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum DECODER_READER {
|
enum DECODER_READER {
|
||||||
// DECODER_ONED_BARCODE = 1,// barcode, which includes UPC_A, UPC_E, EAN_8, EAN_13, CODE_39, CODE_93, CODE_128, ITF, CODABAR
|
DECODER_QRCODE = 0,// QRCODE
|
||||||
DECODER_QRCODE = 2,// QRCODE
|
DECODER_PDF417 = 1,// PDF417
|
||||||
DECODER_PDF417 = 3,// PDF417
|
DECODER_DATAMATRIX = 2,// DATAMATRIX
|
||||||
DECODER_DATAMATRIX = 4,// DATAMATRIX
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<DECODER_READER> vector_DECODER_READER;
|
typedef std::vector<DECODER_READER> vector_DECODER_READER;
|
||||||
@ -874,6 +873,17 @@ typedef std::vector<DECODER_READER> vector_DECODER_READER;
|
|||||||
class CV_EXPORTS_W_SIMPLE CodeDetectorWeChat : public GraphicalCodeDetector
|
class CV_EXPORTS_W_SIMPLE CodeDetectorWeChat : public GraphicalCodeDetector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/** @brief Initialize the CodeDetectorWeChat.
|
||||||
|
*
|
||||||
|
* Parameters allow to load _optional_ Detection and Super Resolution DNN model for better quality.
|
||||||
|
* @param detection_model_path_ model file path for the detection model
|
||||||
|
* @param super_resolution_model_path_ model file path for the super resolution model
|
||||||
|
* @param readers decoder readers
|
||||||
|
* @param detector_iou_thres nms iou threshold for detection part
|
||||||
|
* @param decoder_iou_thres nms iou threshold for decoding part
|
||||||
|
* @param score_thres score threshold for detection part
|
||||||
|
* @param reference_size the length of the image to align during pre-processing before detection
|
||||||
|
*/
|
||||||
CV_WRAP CodeDetectorWeChat(const std::string& detection_model_path_ = "",
|
CV_WRAP CodeDetectorWeChat(const std::string& detection_model_path_ = "",
|
||||||
const std::string& super_resolution_model_path_ = "",
|
const std::string& super_resolution_model_path_ = "",
|
||||||
const std::vector<DECODER_READER>& readers = std::vector<DECODER_READER>(),
|
const std::vector<DECODER_READER>& readers = std::vector<DECODER_READER>(),
|
||||||
@ -882,9 +892,24 @@ public:
|
|||||||
const float score_thres = 0.3,
|
const float score_thres = 0.3,
|
||||||
const int reference_size = 512);
|
const int reference_size = 512);
|
||||||
|
|
||||||
|
/** @brief Set the reference size during the pre-processing before detection.
|
||||||
|
* @param reference_size the length of the image to align during pre-processing before detection
|
||||||
|
*/
|
||||||
CV_WRAP void setDetectorReferenceSize(int reference_size);
|
CV_WRAP void setDetectorReferenceSize(int reference_size);
|
||||||
|
|
||||||
|
/** @brief Set the score threshold during the processing of detection results.
|
||||||
|
* @param score_thres score threshold for detection part
|
||||||
|
*/
|
||||||
CV_WRAP void setDetectorScoreThres(float score_thres);
|
CV_WRAP void setDetectorScoreThres(float score_thres);
|
||||||
|
|
||||||
|
/** @brief Set the detector iou threshold during the processing of detection results.
|
||||||
|
* @param detector_iou_thres nms iou threshold for detection part
|
||||||
|
*/
|
||||||
CV_WRAP void setDetectorIouThres(float iou_thres);
|
CV_WRAP void setDetectorIouThres(float iou_thres);
|
||||||
|
|
||||||
|
/** @brief Set the detector iou threshold during the processing of decoding results.
|
||||||
|
* @param detector_iou_thres nms iou threshold for decoding part
|
||||||
|
*/
|
||||||
CV_WRAP void setDecoderIouThres(float iou_thres);
|
CV_WRAP void setDecoderIouThres(float iou_thres);
|
||||||
|
|
||||||
|
|
||||||
|
@ -325,93 +325,57 @@ std::vector<QBAR_RESULT> QBarDecoder::decode(Mat srcImage, std::vector<DetectInf
|
|||||||
|
|
||||||
parallel_for_(Range(0, int(detect_results.size())), parallelDecode);
|
parallel_for_(Range(0, int(detect_results.size())), parallelDecode);
|
||||||
|
|
||||||
|
this->nms(results, iou_thres);
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QBarDecoder::nms(std::vector<QBAR_RESULT>& results, float NMS_THRESH) {
|
void QBarDecoder::nms(std::vector<QBAR_RESULT>& results, float NMS_THRESH) {
|
||||||
if (results.size() <= 1) return;
|
if (results.size() <= 1) return;
|
||||||
std::unordered_map<int, std::vector<QBAR_RESULT>> class_map;
|
|
||||||
|
|
||||||
for (const auto& result : results) {
|
std::vector<bool> skip(results.size());
|
||||||
class_map[result.typeID].push_back(result);
|
for (size_t i = 0; i < results.size(); ++i)
|
||||||
}
|
skip[i] = false;
|
||||||
|
|
||||||
std::vector<QBAR_RESULT> final_results;
|
// merge overlapped results
|
||||||
|
for (size_t i = 0; i < results.size(); ++i)
|
||||||
|
{
|
||||||
|
if (skip[i] || results[i].points.size() < 4)
|
||||||
|
continue;
|
||||||
|
skip[i] = true;
|
||||||
|
|
||||||
for (auto& pair : class_map) {
|
for (size_t j = i + 1; j < results.size(); ++j)
|
||||||
auto& class_results = pair.second;
|
{
|
||||||
|
if (skip[j] || results[j].points.size() < 4)
|
||||||
|
continue;
|
||||||
|
{
|
||||||
|
std::vector<Point2f> pts_i, pts_j;
|
||||||
|
for (const auto& pt : results[i].points)
|
||||||
|
pts_i.emplace_back(pt.x, pt.y);
|
||||||
|
for (const auto& pt : results[j].points)
|
||||||
|
pts_j.emplace_back(pt.x, pt.y);
|
||||||
|
|
||||||
// leftup: p1 rightdown: p3
|
float area1 = cv::contourArea(pts_i);
|
||||||
std::sort(class_results.begin(), class_results.end(), [](const QBAR_RESULT& a, const QBAR_RESULT& b) {
|
float area2 = cv::contourArea(pts_j);
|
||||||
int widthA = a.points[3].x - a.points[1].x + 1;
|
float intersectionArea = 0.0;
|
||||||
int heightA = a.points[3].y - a.points[1].y + 1;
|
std::vector<cv::Point2f> intersection;
|
||||||
int widthB = b.points[3].x - b.points[1].x + 1;
|
cv::rotatedRectangleIntersection(cv::minAreaRect(pts_i), cv::minAreaRect(pts_j), intersection);
|
||||||
int heightB = b.points[3].y - b.points[1].y + 1;
|
|
||||||
return (widthA * heightA) > (widthB * heightB);
|
|
||||||
});
|
|
||||||
|
|
||||||
std::vector<float> vArea(class_results.size());
|
if (!intersection.empty())
|
||||||
for (size_t i = 0; i < class_results.size(); ++i) {
|
intersectionArea = cv::contourArea(intersection);
|
||||||
vArea[i] = (class_results[i].points[3].x - class_results[i].points[1].x + 1) * (class_results[i].points[3].y - class_results[i].points[1].y + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < class_results.size(); ++i) {
|
double iou = intersectionArea / (area1 + area2 - intersectionArea);
|
||||||
final_results.push_back(class_results[i]);
|
double cover = intersectionArea / min(area1, area2);
|
||||||
if (class_results[i].typeID == 0) continue;
|
if (iou > NMS_THRESH || cover > 0.96) {
|
||||||
// skip oned
|
skip[j] = true;
|
||||||
if (class_results[i].typeID != 6 && class_results[i].typeID != 11 && class_results[i].typeID != 12) continue;
|
results[j].data = "";
|
||||||
|
|
||||||
for (size_t j = i + 1; j < class_results.size();) {
|
|
||||||
float xx1 = std::max(class_results[i].points[1].x, class_results[j].points[1].x);
|
|
||||||
float yy1 = std::max(class_results[i].points[1].y, class_results[j].points[1].y);
|
|
||||||
float xx2 = std::min(class_results[i].points[3].x, class_results[j].points[3].x);
|
|
||||||
float yy2 = std::min(class_results[i].points[3].y, class_results[j].points[3].y);
|
|
||||||
|
|
||||||
float w = std::max(0.0f, xx2 - xx1 + 1);
|
|
||||||
float h = std::max(0.0f, yy2 - yy1 + 1);
|
|
||||||
float inter = w * h;
|
|
||||||
|
|
||||||
float ovr = inter / (vArea[i] + vArea[j] - inter);
|
|
||||||
float cover = inter / std::min(vArea[i], vArea[j]);
|
|
||||||
|
|
||||||
if (ovr >= NMS_THRESH) {
|
|
||||||
class_results.erase(class_results.begin() + j);
|
|
||||||
vArea.erase(vArea.begin() + j);
|
|
||||||
} else if (cover >= 0.96) {
|
|
||||||
if (vArea[i] > vArea[j]) {
|
|
||||||
class_results.erase(class_results.begin() + j);
|
|
||||||
vArea.erase(vArea.begin() + j);
|
|
||||||
} else {
|
|
||||||
class_results[i].points[1] = class_results[j].points[1];
|
|
||||||
class_results[i].points[3] = class_results[j].points[3];
|
|
||||||
class_results.erase(class_results.begin() + j);
|
|
||||||
vArea.erase(vArea.begin() + j);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results = final_results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QBarDecoder::addFormatsToDecodeHints(zxing::DecodeHints &hints) {
|
void QBarDecoder::addFormatsToDecodeHints(zxing::DecodeHints &hints) {
|
||||||
if (readers_.count(QBAR_READER::ONED_BARCODE))
|
|
||||||
{
|
|
||||||
hints.addFormat(BarcodeFormat::CODE_25);
|
|
||||||
hints.addFormat(BarcodeFormat::CODE_39);
|
|
||||||
hints.addFormat(BarcodeFormat::CODE_93);
|
|
||||||
hints.addFormat(BarcodeFormat::CODE_128);
|
|
||||||
hints.addFormat(BarcodeFormat::ITF);
|
|
||||||
hints.addFormat(BarcodeFormat::CODABAR);
|
|
||||||
hints.addFormat(BarcodeFormat::UPC_A);
|
|
||||||
hints.addFormat(BarcodeFormat::UPC_E);
|
|
||||||
hints.addFormat(BarcodeFormat::EAN_8);
|
|
||||||
hints.addFormat(BarcodeFormat::EAN_13);
|
|
||||||
hints.addFormat(BarcodeFormat::RSS_14);
|
|
||||||
}
|
|
||||||
if (readers_.count(QBAR_READER::QRCODE))
|
if (readers_.count(QBAR_READER::QRCODE))
|
||||||
{
|
{
|
||||||
hints.addFormat(BarcodeFormat::QR_CODE);
|
hints.addFormat(BarcodeFormat::QR_CODE);
|
||||||
|
@ -107,10 +107,9 @@ struct QBAR_MODE
|
|||||||
|
|
||||||
// reader config, if not set, try all reader
|
// reader config, if not set, try all reader
|
||||||
enum QBAR_READER{
|
enum QBAR_READER{
|
||||||
ONED_BARCODE = 1, // barcode, which includes UPC_A, UPC_E, EAN_8, EAN_13, CODE_39, CODE_93, CODE_128, ITF, CODABAR
|
QRCODE = 0, // QRCODE
|
||||||
QRCODE = 2, // QRCODE
|
PDF417 = 1, // PDF417
|
||||||
PDF417 = 3, // PDF417
|
DATAMATRIX = 2, // DATAMATRIX
|
||||||
DATAMATRIX = 4, // DATAMATRIX
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////// result struct
|
///////////////////////////// result struct
|
||||||
@ -255,25 +254,6 @@ enum QBAR_CODE_FORMAT{
|
|||||||
FMT_CODE25 = 18,
|
FMT_CODE25 = 18,
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////// debug
|
|
||||||
// enum QBAR_BINARIZER
|
|
||||||
// {
|
|
||||||
// Hybrid = 0,
|
|
||||||
// FastWindow = 1,
|
|
||||||
// SimpleAdaptive = 2,
|
|
||||||
// GlobalHistogram=3,
|
|
||||||
// OTSU=4,
|
|
||||||
// Niblack=5,
|
|
||||||
// Adaptive=6,
|
|
||||||
// HistogramBackground=7
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
// struct QBAR_DEBUG
|
|
||||||
// {
|
|
||||||
// QBAR_BINARIZER binarizer;
|
|
||||||
// };
|
|
||||||
|
|
||||||
enum QBAR_CONFIG_TYPE{
|
enum QBAR_CONFIG_TYPE{
|
||||||
CONFIG_RESERVED0 = 0,
|
CONFIG_RESERVED0 = 0,
|
||||||
CONFIG_RESERVED1 = 1,
|
CONFIG_RESERVED1 = 1,
|
||||||
|
@ -4883,7 +4883,7 @@ CodeDetectorWeChat::CodeDetectorWeChat(const std::string& detection_model_path_,
|
|||||||
CV_Assert(ret == 0);
|
CV_Assert(ret == 0);
|
||||||
|
|
||||||
if (readers.empty()) {
|
if (readers.empty()) {
|
||||||
std::dynamic_pointer_cast<PimplWeChat>(p)->qbarDecode_->setReaders({ONED_BARCODE, QRCODE, PDF417, DATAMATRIX});
|
std::dynamic_pointer_cast<PimplWeChat>(p)->qbarDecode_->setReaders({QRCODE, PDF417, DATAMATRIX});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unordered_set<QBAR_READER> readers_;
|
unordered_set<QBAR_READER> readers_;
|
||||||
|
Loading…
Reference in New Issue
Block a user