【发布时间】:2020-11-23 16:08:20
【问题描述】:
我在金属体上有一个小的蚀刻数据矩阵,经过一些处理(灰度)会产生示例图像。生成的图像大部分都很好,除了模块外部的某些区域与模块边界内的颜色相同。所需要的是仅将模块边界内的区域(白色边框)设为白色。
尝试了 Opencv morph 打开然后关闭,但结果不是很好(不发生解码)。还尝试了 Canny 边缘和填充轮廓,但这会引入噪音。我理论上可以删除一些轮廓,但这会导致图像不准确,因为一些轮廓(主要是黑色区域)位于需要着色的轮廓内,并会导致结果不准确(或没有扫描)。
实现这一点的最佳方式应该是什么(需要更少的图像/点击试用)。白色边界内的区域会根据入射光角度发生变化(水平或垂直间隙)。
// In Java, ZXing is being used to read the pre-processed image
// based on processed bytearray returned from native
// Native process, takes input 480x640 image, crops based on view finder
// which is when we have a 213x213 sized image
cv::resize(img, img, Size(600, 600));
labelUtils.BrightnessAndContrastAuto(img, img);
// identify contour area of datamatrix and crop the selection
vector<Point> contourPoints;
getDataMatrixContour(img,contourPoints);
if (contourPoints.empty) {
threshold(img, img, 100, 255, THRESH_BINARY_INV);
return;
}
// get contour rect which has the code
Rect icRect = cv::boundingRect(contourPoints);
// double scaleFactor = desiredWidth / icRect.width;
// resize bounding rect to have some padding area
LabelUtils::resizeRect(icRect, 1.2);
// make rect even, else cvtColor color fails for odd-sized images
if (icRect.width % 2 != 0)
icRect.width += 1;
if (icRect.height % 2 != 0)
icRect.height += 1;
// crop image to a (sub)scaled even size
labelUtils.submatImage(pImg, icRect);
int sigma = 2, threshold = 5, amount = 10;
sharpenForMetal(img, sigma, threshold, amount);
threshold(img, img, 100, 255, THRESH_BINARY_INV);
return;
【问题讨论】:
-
你能澄清一下你的最终目标是什么吗?最好通过显示解码确实有效的图像。此外,“经过一些处理(灰度)产生示例图像”:请显示您应用的预处理代码,并显示此预处理之前的图像。如果可以退后一步,通常更容易实现目标。
-
@Cris Luengo 添加了代码和整体处理细节。预处理发生在本机中,而解码发生在使用 ZXing 的 Java 中。 Native 接受一个 NV21 字节数组,处理后返回一个字节数组,然后传递给 ZXing 解码器。
标签: python c++ opencv image-processing