opencv 取得红色箭头所指示区域的图像信息

python OpenCV特定颜色线条提取与定位

OpenCV轮廓文档

OpenCV形态变换文档

OpenCV平滑图像文档

  • 问题

  根据图片中红色标签的指示,取得箭头前方小范围区域的图像信息

  • 思路与优化:

  1.图片转HSV格式,应用高斯模糊,去除部分噪音

  2.给出HSV颜色范围,通过inRange(),去除非目标颜色(目标颜色保留,其他均置0,黑色),得到mask

  3.对mask进行二值化操作得到二值图像,此时二值图的白色区域是目标对象,黑色区域是背景

  4.因红色标签内部常常有点状黑色噪音,对二值图像应用形态变换-扩张,扩张(膨胀):内核下至少一个像素为1,则像素元素为1,它增加了图像中的白色区域或前景对象的大小

  5.获取图像轮廓,去除轮廓面积小于预设值(这里用了300)的轮廓,为合格的轮廓计算边界旋转矩形,即定位框

  6.绘制定位框

  • 单个处理的代码
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
def RGB_inv(image):
    #反转BR颜色通道
    b = image[:,:,0].copy()
    r = image[:,:,2].copy()
    image[:,:,0] = r
    image[:,:,2] = b
#读取图像
img = cv.imread("Pic\pic3.jpg")
img = cv.GaussianBlur (img,(5,5),0)
#将图像转化为HSV格式
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
#设定颜色HSV范围,设为红色
low_red= np.array([0,100,100])
upper_red = np.array([10,255,255])
 #去除颜色范围外的其余颜色
mask = cv.inRange(hsv, low_red, upper_red)
# 二值化操作
ret, binary = cv.threshold(mask, 0, 255, cv.THRESH_BINARY)
#形态变换-扩张
kernel = np.ones((5, 5), np.uint8)
dilation = cv.dilate(binary,kernel,iterations = 1)
plt.subplot(121)
plt.imshow(dilation,'gray')
plt.title('dilation')
plt.xticks([]),plt.yticks([])
#获取图像轮廓坐标,其中contours为坐标值,此处只检测外形轮廓
contours, hierarchy = cv.findContours(dilation, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
print(len(contours))
if len(contours) > 0:
    rects = [cv.minAreaRect (c) for c in contours if cv.contourArea(c) >300]
    boxs = [np.int0(cv.boxPoints (rect) )for rect in rects]
    cv.drawContours (img,boxs,-1,(0,255,0),2)
    #将绘制的图像保存并展示
    RGB_inv(img)
    plt.subplot(122)
    plt.imshow(img,'gray')
    plt.title('pic3.jpg')
    plt.xticks([]),plt.yticks([])
    plt.show()
    k = cv.waitKey(0)
    if k == ord("s"):
        cv.imwrite("x.jpg", img)#图像另存为
View Code

  • 批量处理的代码
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
def RGB_inv(image):
    b = image[:,:,0].copy()
    r = image[:,:,2].copy()
    image[:,:,0] = r
    image[:,:,2] = b
def handle(img_path,i):
    img = cv.imread(img_path)
    img = cv.GaussianBlur (img,(5,5),0)
    #将图像转化为HSV格式
    hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
    #设定颜色HSV范围,设为红色
    low_red= np.array([0,100,100])
    upper_red = np.array([10,255,255])
     #去除颜色范围外的其余颜色
    mask = cv.inRange(hsv, low_red, upper_red)
    # 二值化操作
    ret, binary = cv.threshold(mask, 0, 255, cv.THRESH_BINARY)
    #形态变换
    kernel = np.ones((5, 5), np.uint8)
    dilation = cv.dilate(binary,kernel,iterations = 1)
    #获取图像轮廓坐标,其中contours为坐标值,此处只检测外形轮廓
    contours, hierarchy = cv.findContours(dilation, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    print(img_path+" get "+str(len(contours))+" cnt")
    if len(contours) > 0:
        rects = [cv.minAreaRect (c) for c in contours if  cv.contourArea(c) >300]
        print(img_path+" remain "+str(len(rects))+" cnt")
        boxs = [np.int0(cv.boxPoints (rect) )for rect in rects]
        cv.drawContours (img,boxs,-1,(0,255,0),2)
        #将绘制的图像保存并展示
        RGB_inv(img)
        plt.subplot(2,3,i)
        plt.imshow(img,'gray')
        plt.title(img_path+" get "+str(len(rects)))
        plt.xticks([]),plt.yticks([])
#读取图像
n = 1
for i in range(19,23):
    handle("Pic\pic"+str(i)+".jpg",n)
    n += 1
plt.show()
View Code

  批量处理的效果

  

 

 

 

 

 

 

  • 待解决的问题

  1.目前针对红色划定的HSV颜色范围,不适用于所有的图片,部分图片通过当前参数的inRange()过滤后,仅留下黑色

   目前的颜色范围还会留下误拍摄进的手掌区域

  2.定位框不能全部都准确地框住红色箭头标签本身,有的只框住了部分,有的不能与箭头长边平行,倾斜放置,

  但我们的最终目标是找到箭头指示的区域,所以定位框的问题不是非解决不可

  3.确定箭头轮廓的中心,根据箭头轮廓的凸起,确定向量;

  对箭头轮廓做一条拟合线,

  从中心出发,依照向量,沿拟合线前进一定距离作为圆心,取设定半径画圆,取得图像信息 

posted @ 2022-02-20 16:45  许培风  阅读(283)  评论(0)    收藏  举报