大体思路(需要图片较清晰):
1、加载图像并灰度化
2、使用Scharr算子进行梯度运算,并使用x梯度减y梯度
3、进行平滑处理,去除高频噪声,并二值化
4、进行闭运算,用于将条码间距减小
5、多次腐蚀膨胀去小斑点
6、寻找轮廓,识别面积最大的,绘制标记。
效果如下:
原始图片 识别标记的结果参考代码:
# 检测图片内的条码 import numpy as np import argparse import imutils import cv2 # construct the argument parse and parse the arguments # ap = argparse.ArgumentParser() # ap.add_argument("-i", "--image", required = True, help = "path to the image file") # args = vars(ap.parse_args()) # 读取图片并灰度化 image = cv2.imread("C:/Users/zyh/Desktop/031.png") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 计算图像的Scharr梯度幅度表示 # 在x、y方向分别计算 ddepth = cv2.cv.CV_32F if imutils.is_cv2() else cv2.CV_32F gradX = cv2.Sobel(gray, ddepth=ddepth, dx=1, dy=0, ksize=-1) gradY = cv2.Sobel(gray, ddepth=ddepth, dx=0, dy=1, ksize=-1) # 从x中减去y gradient = cv2.subtract(gradX, gradY) gradient = cv2.convertScaleAbs(gradient) # 平滑并二值处理 blurred = cv2.blur(gradient, (9, 9)) (_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY) # 进行闭运算 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7)) closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) # 进行多次腐蚀膨胀 closed = cv2.erode(closed, None, iterations = 4) closed = cv2.dilate(closed, None, iterations = 4) # 在阈值图像中找到轮廓,然后对轮廓按面积进行排序,只保留最大的 cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) c = sorted(cnts, key = cv2.contourArea, reverse = True)[0] # 计算最大轮廓的边框 rect = cv2.minAreaRect(c) box = cv2.cv.BoxPoints(rect) if imutils.is_cv2() else cv2.boxPoints(rect) box = np.int0(box) # 绘制边框 cv2.drawContours(image, [box], -1, (0, 255, 0), 3) cv2.imshow("Image", image) cv2.waitKey(0)