我目前正在使用 openCv 做一些计算机视觉。我有一个瓶子样品,上面有标签。我试图确定瓶子上什么时候没有标签。标签为长方形。
我已经使用 Canny 进行了边缘检测。我尝试使用 findcountour() 来检测瓶子是否有内部轮廓(这将代表矩形标签)。
我目前正在使用 openCv 做一些计算机视觉。我有一个瓶子样品,上面有标签。我试图确定瓶子上什么时候没有标签。标签为长方形。
我已经使用 Canny 进行了边缘检测。我尝试使用 findcountour() 来检测瓶子是否有内部轮廓(这将代表矩形标签)。
如果您的问题如此简单,只需使用矩形缩小图像即可。
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(你应该检查这个)。如果有标签,那么在从未标记的像素中计算零/非零像素时,您会看到不同的结果。
#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;
}
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() 也将起作用。
参考: