【问题标题】:Detect black ink blob on paper - Opencv Android检测纸上的黑色墨水斑点 - Opencv Android
【发布时间】:2017-04-08 06:02:00
【问题描述】:

我是 openCV 的新手,我一直在研究为 Android 提供的示例。

我的目标是检测颜色斑点,所以我从颜色斑点检测样本开始。

我正在将彩色图像转换为灰度,然后使用二进制阈值进行阈值化。

背景是白色的,斑点是黑色的。我想检测那些黑色斑点。另外,我想用彩色画出它们的轮廓,但我不能这样做,因为图像是黑白的。

我已经设法在灰度中完成了这一点,但我不喜欢如何绘制轮廓,这就像颜色容差太高并且轮廓比实际的 blob 大(也许 blob 太小了?)。我猜我所说的这种“宽容”与 setHsvColor 有关,但我不太了解那种方法。

提前致谢!最好的问候

更新更多信息

我要跟踪的图像是墨水分裂。想象一张白色的纸,上面有黑色的墨水裂开。现在我正在实时进行(相机视图)。实际应用会拍照并分析该照片。

如上所述,我从 openCV GitHub 存储库获取了 color-blob-detection 示例 (android)。我在 onCameraFrame 方法中添加了这段代码(以便将其实时转换为黑白)。转换已完成,所以我不介意墨水是黑色、蓝色、红色:

mRgba = inputFrame.rgba();
/**************************************************************************/
/** BLACK AND WHITE **/
// Convert to Grey
Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA, 4);

Mat blackAndWhiteMat = new Mat ( H, W, CvType.CV_8U, new Scalar(1));
double umbral = 100.0;
Imgproc.threshold(mRgba, blackAndWhiteMat , umbral, 255, Imgproc.THRESH_BINARY);

// convert back to bitmap for displaying
Bitmap resultBitmap = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
blackAndWhiteMat.convertTo(blackAndWhiteMat, CvType.CV_8UC1);
Utils.matToBitmap(blackAndWhiteMat, resultBitmap);
/**************************************************************************/

这可能不是最好的方法,但它确实有效。

现在我想检测黑色斑点(墨水分裂)。我猜它们被检测到是因为 Logcat(示例应用程序的日志条目)会抛出检测到的轮廓数,但我无法看到它们,因为图像是黑白的,并且我希望轮廓是红色的,例如。

这是一个示例图像:-

这是我使用 RGB 得到的结果(按原样进行颜色斑点检测,而不是黑白图像)。注意没有检测到小斑点。 (是否有可能检测到它们?还是它们太小了?)

感谢您的帮助!如果您需要更多信息,我很乐意更新此问题

更新:颜色斑点检测示例的 GitHub 存储库(第二张图片)

GitHub Repo of openCV sample for Android

【问题讨论】:

  • 您好,您的问题信息量不大。请上传输入图像以及您的处理结果。这将有助于理解问题。举个例子,看看这个问题:stackoverflow.com/q/10168686/1874627
  • @saurabheights 感谢您的评论。我将用更多信息更新问题,并编码 sn-ps
  • 好的,我可以提出一些建议。只要有良好的对比度,无论是小斑点还是大斑点都不是问题。如果您能找到大多数像素为白色的区域(检查连接组件),您将拥有您的纸张区域。如果你发现一个子区域是黑色的(远低于纸区域的平均强度),你会发现你所有的斑点。要绘制轮廓,您需要找到黑色区域的凸包。此外,您能否上传代码(或链接)以了解如何实现第二个图像输出。来晚了,明天去看看。感谢您的精彩更新。
  • 一个小点:连接组件可能是 blob 检测的工作方式(因此它可能不是解决问题的新方法)。在阈值化之前应用一些先前的对比度增强和高斯模糊(以减少任何噪声)。并保存您的中间输出。动态生成阈值(100 值并不总是有效,使用平均强度的 x%)
  • 再次感谢@saurabheights!我将把链接放到颜色斑点检测示例。可悲的是,我是这个计算机视觉世界的新手,我不明白如何实现你的建议。我理解它(我认为),但不知道如何使用 openCV 来做到这一点

标签: android opencv threshold blobs


【解决方案1】:

该解决方案基于自适应图像阈值和使用连通分量算法的组合。

假设 - 纸张是图像中最亮的区域,而纸张上的墨点是最暗的区域。

from random import Random
import numpy as np
import cv2

def random_color(random):
    """
    Return a random color
    """
    icolor = random.randint(0, 0xFFFFFF)
    return [icolor & 0xff, (icolor >> 8) & 0xff, (icolor >> 16) & 0xff]

#Read as Grayscale
img = cv2.imread('1-input.jpg', 0)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

# Gaussian to remove noisy region, comment to see its affect.
img = cv2.medianBlur(img,5)

#Find average intensity to distinguish paper region
avgPixelIntensity = cv2.mean( img )
print "Average intensity of image: ", avgPixelIntensity[0]

# Generate mask to distinguish paper region
#0.8 - used to ignore ill-illuminated region of paper
mask = cv2.inRange(img, avgPixelIntensity[0]*0.8, 255) 
mask = 255 - mask
cv2.imwrite('2-maskedImg.jpg', mask)

#Approach 1
# You need to choose 4 or 8 for connectivity type(border pixels)
connectivity = 8
# Perform the operation
output = cv2.connectedComponentsWithStats(mask, connectivity, cv2.CV_8U)
# The first cell is the number of labels
num_labels = output[0]
# The second cell is the label matrix
labels = output[1]
# The third cell is the stat matrix
stats = output[2]
# The fourth cell is the centroid matrix
centroids = output[3]

cv2.imwrite("3-connectedcomponent.jpg", labels)
print "Number of labels", num_labels, labels

# create the random number
random = Random()

for i in range(1, num_labels):
    print stats[i, cv2.CC_STAT_LEFT], stats[i, cv2.CC_STAT_TOP], stats[i, cv2.CC_STAT_WIDTH], stats[i, cv2.CC_STAT_HEIGHT]
    cv2.rectangle(cimg, (stats[i, cv2.CC_STAT_LEFT], stats[i, cv2.CC_STAT_TOP]), 
        (stats[i, cv2.CC_STAT_LEFT] + stats[i, cv2.CC_STAT_WIDTH], stats[i, cv2.CC_STAT_TOP] + stats[i, cv2.CC_STAT_HEIGHT]), random_color(random), 2)

cv2.imwrite("4-OutputImage.jpg", cimg)

输入图像

来自阈值和反转操作的蒙版图像。

连接组件的使用。

在输入图像上叠加连接组件的输出。

【讨论】:

  • 发布后,我注意到橙色的大矩形。如果您想忽略它,它应该是与图像相比的简单区域估计。或者像检查纵横比一样,blob 将具有几乎相同的高度/宽度。一个问题,这是干什么用的?
  • @sebasira 这是审美的一部分,呵呵。既然可以使用彩虹,为什么还要使用黑匣子!此外,黑色墨块周围的黑框也不会很明显。
  • @sebasira:你能告诉我进展如何吗?它的准确性和陷阱?花点时间回答,不要着急。
  • 它非常非常接近我正在寻找的东西。我已经设法构建和测试你的例子。我花了一些时间来设置一切。我仍在努力,也在考虑一些改进。现在我将尝试在斑点上绘制轮廓,而不是显示一个矩形。非常感谢您,我会及时通知您,或者如果需要,请打开一个新问题
猜你喜欢
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
  • 2017-07-01
相关资源
最近更新 更多