mirror of
https://github.com/opencv/opencv.git
synced 2025-06-11 03:33:28 +08:00
add intro to params
This commit is contained in:
parent
b77047fc08
commit
e548e59cd5
@ -863,10 +863,9 @@ public:
|
||||
};
|
||||
|
||||
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 = 2,// QRCODE
|
||||
DECODER_PDF417 = 3,// PDF417
|
||||
DECODER_DATAMATRIX = 4,// DATAMATRIX
|
||||
DECODER_QRCODE = 0,// QRCODE
|
||||
DECODER_PDF417 = 1,// PDF417
|
||||
DECODER_DATAMATRIX = 2,// DATAMATRIX
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
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_ = "",
|
||||
const std::string& super_resolution_model_path_ = "",
|
||||
const std::vector<DECODER_READER>& readers = std::vector<DECODER_READER>(),
|
||||
@ -882,9 +892,24 @@ public:
|
||||
const float score_thres = 0.3,
|
||||
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);
|
||||
|
||||
/** @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);
|
||||
|
||||
/** @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);
|
||||
|
||||
/** @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);
|
||||
|
||||
|
||||
|
@ -325,93 +325,57 @@ std::vector<QBAR_RESULT> QBarDecoder::decode(Mat srcImage, std::vector<DetectInf
|
||||
|
||||
parallel_for_(Range(0, int(detect_results.size())), parallelDecode);
|
||||
|
||||
this->nms(results, iou_thres);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void QBarDecoder::nms(std::vector<QBAR_RESULT>& results, float NMS_THRESH) {
|
||||
if (results.size() <= 1) return;
|
||||
std::unordered_map<int, std::vector<QBAR_RESULT>> class_map;
|
||||
|
||||
for (const auto& result : results) {
|
||||
class_map[result.typeID].push_back(result);
|
||||
}
|
||||
std::vector<bool> skip(results.size());
|
||||
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) {
|
||||
auto& class_results = pair.second;
|
||||
for (size_t j = i + 1; j < results.size(); ++j)
|
||||
{
|
||||
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
|
||||
std::sort(class_results.begin(), class_results.end(), [](const QBAR_RESULT& a, const QBAR_RESULT& b) {
|
||||
int widthA = a.points[3].x - a.points[1].x + 1;
|
||||
int heightA = a.points[3].y - a.points[1].y + 1;
|
||||
int widthB = b.points[3].x - b.points[1].x + 1;
|
||||
int heightB = b.points[3].y - b.points[1].y + 1;
|
||||
return (widthA * heightA) > (widthB * heightB);
|
||||
});
|
||||
float area1 = cv::contourArea(pts_i);
|
||||
float area2 = cv::contourArea(pts_j);
|
||||
float intersectionArea = 0.0;
|
||||
std::vector<cv::Point2f> intersection;
|
||||
cv::rotatedRectangleIntersection(cv::minAreaRect(pts_i), cv::minAreaRect(pts_j), intersection);
|
||||
|
||||
std::vector<float> vArea(class_results.size());
|
||||
for (size_t i = 0; i < class_results.size(); ++i) {
|
||||
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);
|
||||
}
|
||||
if (!intersection.empty())
|
||||
intersectionArea = cv::contourArea(intersection);
|
||||
|
||||
for (size_t i = 0; i < class_results.size(); ++i) {
|
||||
final_results.push_back(class_results[i]);
|
||||
if (class_results[i].typeID == 0) continue;
|
||||
// skip oned
|
||||
if (class_results[i].typeID != 6 && class_results[i].typeID != 11 && class_results[i].typeID != 12) continue;
|
||||
|
||||
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++;
|
||||
double iou = intersectionArea / (area1 + area2 - intersectionArea);
|
||||
double cover = intersectionArea / min(area1, area2);
|
||||
if (iou > NMS_THRESH || cover > 0.96) {
|
||||
skip[j] = true;
|
||||
results[j].data = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results = final_results;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
hints.addFormat(BarcodeFormat::QR_CODE);
|
||||
|
@ -107,10 +107,9 @@ struct QBAR_MODE
|
||||
|
||||
// reader config, if not set, try all 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 = 2, // QRCODE
|
||||
PDF417 = 3, // PDF417
|
||||
DATAMATRIX = 4, // DATAMATRIX
|
||||
QRCODE = 0, // QRCODE
|
||||
PDF417 = 1, // PDF417
|
||||
DATAMATRIX = 2, // DATAMATRIX
|
||||
};
|
||||
|
||||
///////////////////////////// result struct
|
||||
@ -255,25 +254,6 @@ enum QBAR_CODE_FORMAT{
|
||||
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{
|
||||
CONFIG_RESERVED0 = 0,
|
||||
CONFIG_RESERVED1 = 1,
|
||||
|
@ -4883,7 +4883,7 @@ CodeDetectorWeChat::CodeDetectorWeChat(const std::string& detection_model_path_,
|
||||
CV_Assert(ret == 0);
|
||||
|
||||
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 {
|
||||
unordered_set<QBAR_READER> readers_;
|
||||
|
Loading…
Reference in New Issue
Block a user