Browse Source

【bug修复】(黄根)解决答题卡因二维码位置离顶部距离过大而被误判定为二维码批次不存在的问题 & 优化定位点识别逻辑
【工作量】8h
【评审人】

huanggen 2 years ago
parent
commit
342eaba1d1
2 changed files with 26 additions and 9 deletions
  1. 24 9
      app/src/main/cpp/paperPreIdentify.cpp
  2. 2 0
      app/src/main/cpp/paperPreIdentify.h

+ 24 - 9
app/src/main/cpp/paperPreIdentify.cpp

@@ -52,7 +52,7 @@ size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
     return size * nmemb;
 }
 
-string ZbarDecoder(Mat img)
+string ZbarDecoder(Mat img, int & nAnchorsToQrCode)
 {
     string result;
     ImageScanner scanner;
@@ -66,7 +66,10 @@ string ZbarDecoder(Mat img)
     // extract results
     Image::SymbolIterator symbol = image.symbol_begin();
     if (symbol != image.symbol_end())
+    {
+        nAnchorsToQrCode = symbol->get_location_y(0);
         result = symbol->get_data();
+    }
     image.set_data(NULL, 0);
     return result;
 }
@@ -75,6 +78,7 @@ paperPreIdentify::paperPreIdentify(int nSchoolId)
 {
     m_nSchoolId = nSchoolId;
     m_sCardId = "";
+    m_nAnchorsToQrCode = 0;
 }
 
 paperPreIdentify::~paperPreIdentify()
@@ -118,20 +122,23 @@ string paperPreIdentify::readQrCode(PaperPage sPage)
     {
         string strPath = i == 0 ? sPage.firstPage : sPage.secondPage;
         Mat tImg = imread(strPath);
-        Mat roiMat = tImg(Rect(0, 0, tImg.cols / 4, tImg.rows / 6));
+        Mat roiMat = tImg(Rect(0, 0, tImg.cols / 4, tImg.rows / 5));
         Mat imgGray;
         cvtColor(roiMat, imgGray, CV_BGR2GRAY);  // 灰度化
-        QRCodeDetector tDetector;
+//        QRCodeDetector tDetector;
 //        strRet = tDetector.detectAndDecode(roiMat);
-        strRet = ZbarDecoder(imgGray);
+        m_nAnchorsToQrCode = 0;
+        strRet = ZbarDecoder(imgGray, m_nAnchorsToQrCode);
         if (strRet.length() > 0)
             break;
         else
         {
-            roiMat = tImg(Rect(tImg.cols * 3 / 4, tImg.rows * 5 / 6, tImg.cols / 4, tImg.rows / 6));
+            roiMat = tImg(Rect(tImg.cols * 3 / 4, tImg.rows * 4 / 5, tImg.cols / 4, tImg.rows / 5));
+            cvtColor(roiMat, imgGray, CV_BGR2GRAY);
 //            strRet = tDetector.detectAndDecode(roiMat);
             //opencv容易出现识别出二维码但是decode返回空的问题,改用ZBar库识别二维码
-            strRet = ZbarDecoder(imgGray);
+            strRet = ZbarDecoder(imgGray, m_nAnchorsToQrCode);
+            m_nAnchorsToQrCode += tImg.rows * 4 / 5;
             if (strRet.length() > 0)
                 break;
         }
@@ -210,7 +217,10 @@ bool paperPreIdentify::getCardTemplate(string strCardId, bool bUseTestIp)
         m_SchemeParam.dImgHeight= root["data"]["pages"][0]["imge"]["height"].asInt();
         int nAchorsWidth = root["data"]["pages"][0]["location"][0]["width"].asInt();
         int nAchorsHeight = root["data"]["pages"][0]["location"][0]["height"].asInt();
+        int nQrCodeY = root["data"]["pages"][0]["QrCode"]["y"].asInt();
+
         m_SchemeParam.dAnchorsHeight = nAchorsHeight;
+        m_SchemeParam.nAnchorsToQrcodeDis = nQrCodeY;
         for (int i = 0; i < 4; i++)
         {
             if (i < 2) {
@@ -235,13 +245,18 @@ bool paperPreIdentify::findTopAnchors(Mat tMat)
 {
     //根据图片像素比例调整定位点检查区域高度
     double dLocPointHeight = m_SchemeParam.dAnchorsHeight;
-    m_SchemeParam.nAnchorsTopRange = dLocPointHeight * 6 * tMat.rows / m_SchemeParam.dImgHeight;
-    m_SchemeParam.nAnchorsBottomRange = dLocPointHeight * 7 * tMat.rows / m_SchemeParam.dImgHeight;
+    int nDelta = tMat.rows / m_SchemeParam.dImgHeight;
+    m_SchemeParam.nAnchorsTopRange = dLocPointHeight * 6 * nDelta;
+    m_SchemeParam.nAnchorsBottomRange = dLocPointHeight * 7 * nDelta;
+    if(m_nAnchorsToQrCode > tMat.rows / 2)
+        m_SchemeParam.nAnchorsBottomRange = m_nAnchorsToQrCode + (m_SchemeParam.nAnchorsToQrcodeDis - dLocPointHeight) * nDelta - 5;
+    else if(m_nAnchorsToQrCode > 0 && m_nAnchorsToQrCode < tMat.rows / 2)
+        m_SchemeParam.nAnchorsTopRange = m_nAnchorsToQrCode - (m_SchemeParam.nAnchorsToQrcodeDis - dLocPointHeight) * nDelta + 5;
     int range = m_SchemeParam.nAnchorsTopRange;
     //LOGFMTI("MyFindDingWeiDian 1 range=%d", range);
     CvRect roi[4] = {//上下左右 roi
             cvRect(0, 0, tMat.cols, min(range, tMat.rows)),
-            cvRect(0, tMat.rows - min(range, tMat.rows) - 1, tMat.cols, min(range, tMat.rows)),
+            cvRect(0, min(tMat.rows - min(range, tMat.rows), m_SchemeParam.nAnchorsBottomRange) - 1, tMat.cols, min(range, tMat.rows)),
             cvRect(0, 0, min(range, tMat.cols), tMat.rows),
             cvRect(tMat.cols - min(range, tMat.cols) - 1, 0, min(range, tMat.cols), tMat.rows)
     };

+ 2 - 0
app/src/main/cpp/paperPreIdentify.h

@@ -57,6 +57,7 @@ struct SchemeParam
 {
     int nAnchorsTopRange;                                                                           //定位点顶部检测区域范围
     int nAnchorsBottomRange;                                                                        //定位点底部检测区域范围
+    int nAnchorsToQrcodeDis;                                                                        //左上角定位点至二维码左上角的y轴像素距离
     double dAnchorsWMaxRate;                                                                        //模板数据中定位点宽度的最大倍率
     double dAnchorsHMaxRate;                                                                        //模板数据中定位点高度的最大倍率
     double dAnchorsWMinRate;                                                                        //模板数据中定位点宽度的最小倍率
@@ -112,6 +113,7 @@ private:
     int getBalckAreaCount(Mat& tMat);                                                               //统计图像区域黑色点数量
 
 private:
+    int m_nAnchorsToQrCode;                                                                         //定位点离二维码左上角点的像素距离(y轴方向)
     int m_nSchoolId;                                                                                //学校ID
     std::string m_sCardId;                                                                          //答题卡ID
     SchemeParam m_SchemeParam;