在纸上检测黑色墨水blob - Opencv Android

时间:2016-11-24 03:58:26

标签: android opencv threshold blobs

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

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

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

背景为白色,斑点为黑色。我想检测那些黑色斑点。此外,我想画出他们的轮廓颜色,但我无法做到,因为图像是黑白的。

我已经设法以灰度方式实现了这一目标,但我不喜欢如何绘制轮廓,它就像颜色容差太高而且轮廓比实际的blob大(可能blob太小了?)。我想我所说的“容忍度”与setHsvColor有关,但我不太明白这种方法。

提前致谢!最诚挚的问候

更新更多信息

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

正如我上面所说,我从openCV GitHub repo中获取了color-blob-detection sample(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(示例应用程序的日志条目)会抛出检测到的轮廓数量,但我无法看到它们,因为图像是黑白的,我希望轮廓为红色,例如。

以下是一个示例图片: - enter image description here

这就是我使用RGB(颜色斑点检测,而不是黑白图像)。注意没有检测到小斑点。 (有可能检测到它们吗?还是它们太小?) enter image description here

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

更新:彩色斑点检测样本的GitHub回购(第二张图片)

GitHub Repo of openCV sample for Android

1 个答案:

答案 0 :(得分:0)

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

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

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)

输入图像

The Input Image

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

Masked Image

使用已连接的组件。

CC Image

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

Output Image