2

在此处输入图像描述在此处输入图像描述在此处输入图像描述我目前正在使用 openCv 做一些计算机视觉。我有一个瓶子样品,上面有标签。我试图确定瓶子上什么时候没有标签。标签为长方形。

我已经使用 Canny 进行了边缘检测。我尝试使用 findcountour() 来检测瓶子是否有内部轮廓(这将代表矩形标签)。

4

4 回答 4

5

如果您的问题如此简单,只需使用矩形缩小图像即可。

cv::Mat image = imread("image.png");
cv::Rect labelRegion(50, 200, 50, 50);
cv::Mat labelImage = image(labelRegion);

然后将您的图像区域分解为三个通道。

cv::Mat channels[3];
cv::split(labelImage, channels);

cv::Mat labelImageRed = channels[2];
cv::Mat labelImageGreen = channels[1];
cv::Mat labelImageBlue = channels[0];

然后对这些通道图像中的每一个进行阈值处理,并计算零/非零像素的数量。

I'm not providing code for this part!

如果图像上没有标签,则每个通道的值都大于~200(你应该检查这个)。如果有标签,那么在从未标记的像素中计算零/非零像素时,您会看到不同的结果。

于 2013-11-12T16:39:04.150 回答
2
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;
int main()
{

    Mat img=imread("c:/data/bottles/1.png");
    Mat gray;
    cvtColor(img,gray,CV_BGR2GRAY);
    resize(gray,gray,Size(50,100));
    Sobel(gray,gray,CV_16SC1,0,1);
    convertScaleAbs(gray,gray);
    if(sum(gray)[0]<130000)
    {       
        cout<<"no label";
    }else{
        cout<<"has label";
    }
    imshow("gray",gray);
    waitKey();
    return 0;
}
于 2013-11-12T17:06:19.713 回答
1

我猜只要看看瓶子上是否有文字就足够了(如果是,那么它有一个标签,反之亦然)..你可以查看一个像这样的项目..里面有很多论文这片区域; 一些比较有名的是由斯坦福 CV 小组完成的 - 12 ..

高温高压

于 2013-11-12T15:48:42.907 回答
1

guneykayim 建议图像分割,我认为这是最简单的方法。我只是补充一点...

我的建议是您将 BGR 图像转换为 YCbCr,然后在 Cb 和 Cr 通道中查找与标签颜色匹配的值。即使瓶子上的照明条件发生变化,这也可以让您轻松区分颜色(黑暗照明的瓶子最终会使白色区域呈现深灰色,如果您有灰色标签,这可能是一个问题)

像这样的东西应该在 python 中工作:

# Required moduls
import cv2
import numpy

# Convert image to YCrCb
imageYCrCb = cv2.cvtColor(sourceImage,cv2.COLOR_BGR2YCR_CB)

# Constants for finding range of label color in YCrCb
# a, b, c and d need to be defined
min_YCrCb = numpy.array([0,a,b],numpy.uint8) 
max_YCrCb = numpy.array([0,c,d],numpy.uint8)

# Threshold the image to produce blobs that indicate the labeling
labelRegion = cv2.inRange(imageYCrCb,min_YCrCb,max_YCrCb)

# Just in case you are interested in going an extra step
contours, hierarchy = cv2.findContours(labelRegion, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Draw the contour on the source image
for i, c in enumerate(contours):
    area = cv2.contourArea(c)
    if area > minArea: # minArea needs to be defined, try 300 square pixels
        cv2.drawContours(sourceImage, contours, i, (0, 255, 0), 3)

如果您决定使用 BGR 图像,函数 cv2.inRange() 也将起作用。

参考:

http://en.wikipedia.org/wiki/YCbCr

于 2013-11-12T17:29:04.163 回答