Exclude draw data when logo exist 92/315292/2
authorKwanghoon Son <k.son@samsung.com>
Mon, 29 Jul 2024 12:04:45 +0000 (21:04 +0900)
committerKwanghoon Son <k.son@samsung.com>
Tue, 30 Jul 2024 01:37:54 +0000 (10:37 +0900)
When draw logo, data area should clean.
Also fix circle draw position.

Change-Id: I80d60e6ae8ab3ac427314b493441cc76265e3d38
Signed-off-by: Kwanghoon Son <k.son@samsung.com>
mv_barcode/barcode_generator/src/BarcodeGenerator.cpp

index 22d1a3a7ba7a8d2e611cb8774058f80e2587e513..c78bcb32c5bf2e2fed602874d01aa0e91eb51ddd 100644 (file)
@@ -560,9 +560,7 @@ static void drawFinderPattern(cv::Mat &resize_buf, int resize_scale, int org_hei
                                __round_rect(resize_buf, rect, color);
                                break;
                        case MV_BARCODE_GENERATE_ATTR_SHAPE_CIRCLE:
-                               cv::circle(resize_buf,
-                                                  cv::Point((x + 2 * sz) * resize_scale + resize_scale / 2,
-                                                                        (y + 2 * sz) * resize_scale + resize_scale / 2),
+                               cv::circle(resize_buf, cv::Point((posx[pos] + 7) * resize_scale, (posy[pos] + 7) * resize_scale),
                                                   finder_lenght / 2 * resize_scale, color, -1);
                                break;
 
@@ -573,30 +571,53 @@ static void drawFinderPattern(cv::Mat &resize_buf, int resize_scale, int org_hei
        }
 }
 
+static inline float l2_distance(int x1, int y1, int x2, int y2)
+{
+       return std::sqrt(std::pow((x2 - x1), 2) + std::pow((y2 - y1), 2));
+}
+
+static bool is_inside_logo(int x, int y, int org_width, int org_height, mv_barcode_generate_attr_shape_e shape)
+{
+       if (shape == MV_BARCODE_GENERATE_ATTR_SHAPE_CIRCLE) {
+               float distance = l2_distance(x, y, org_width / 2, org_height / 2);
+               return distance < (float) org_width * 0.13f;
+       }
+
+       return (std::abs(x - org_width / 2) < (float) org_width * 0.12f) &&
+                  (std::abs(y - org_height / 2) < (float) org_height * 0.12f);
+}
+
 /*
  * Draw data pattern
  * buf already resize x2(by libzint), so finder size is not 7x7, but 14x14.
  * Loop also jump 2 pixel each.
  */
 static void drawDataPattern(cv::Mat &resize_buf, const cv::Mat &buf, int resize_scale, int org_height, int org_width,
-                                                       mv_barcode_generate_attr_shape_e shape)
+                                                       const BarcodeConfig &config)
 {
        for (int y = 2; y < org_height - 2; y += 2) {
                for (int x = 2; x < org_width - 2; x += 2) {
                        if (is_finder(x, y, org_width, org_height) || buf.at<unsigned char>(y, x, 0) == 255)
                                continue;
-                       if (shape == MV_BARCODE_GENERATE_ATTR_SHAPE_RECT)
+                       /*
+                        * We can find overlap area using opencv Mat inRange, but it's too slow.
+                        * So we use simple distance check algorithm.
+                        */
+                       if (!config.logo_path.empty() && is_inside_logo(x + 1, y + 1, org_height, org_width, config.finder_shape))
+                               continue;
+
+                       if (config.data_shape == MV_BARCODE_GENERATE_ATTR_SHAPE_RECT)
                                cv::rectangle(resize_buf,
                                                          cv::Rect(x * resize_scale, y * resize_scale, resize_scale * 2, resize_scale * 2),
                                                          cv::Scalar(0), -1);
                        else
                                /* if radius is same as resize_scale, data look so dense, so -4 */
-                               cv::circle(resize_buf,
-                                                  cv::Point(x * resize_scale + resize_scale / 2, y * resize_scale + resize_scale / 2),
-                                                  resize_scale - 4, cv::Scalar(0), -1);
+                               cv::circle(resize_buf, cv::Point((x + 1) * resize_scale, (y + 1) * resize_scale), resize_scale - 4,
+                                                  cv::Scalar(0), -1);
                }
        }
 }
+
 static void drawDesignQR(cv::Mat &buf, const BarcodeConfig &config)
 {
        if (config.type != MV_BARCODE_QR || (config.data_shape == MV_BARCODE_GENERATE_ATTR_SHAPE_RECT &&
@@ -606,7 +627,7 @@ static void drawDesignQR(cv::Mat &buf, const BarcodeConfig &config)
        cv::Mat resize_buf(buf.rows * resize_scale, buf.cols * resize_scale, CV_8UC1, cv::Scalar(255));
 
        drawFinderPattern(resize_buf, resize_scale, buf.rows, buf.cols, config.finder_shape);
-       drawDataPattern(resize_buf, buf, resize_scale, buf.rows, buf.cols, config.data_shape);
+       drawDataPattern(resize_buf, buf, resize_scale, buf.rows, buf.cols, config);
 
        cv::cvtColor(resize_buf, buf, cv::COLOR_GRAY2BGR);
 }