基于HSV的目标区域识别和框选(python-opencv)

HSV的确定

首先我们要确定我们要提取目标颜色的HSV范围。
这里参考了:【OpenCV实战】基于HSV的颜色分割Python实现(含Python代码)
代码如下:

import cv2

# 滑动条的回调函数,获取滑动条位置处的值
def empty(a):
    h_min = cv2.getTrackbarPos("Hue Min","TrackBars")
    h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
    s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
    s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
    v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
    v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
    print(h_min, h_max, s_min, s_max, v_min, v_max)
    return h_min, h_max, s_min, s_max, v_min, v_max

path = 'Resources/11.jpg'
# 创建一个窗口,放置6个滑动条
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars",640,240)
cv2.createTrackbar("Hue Min","TrackBars",0,179,empty)
cv2.createTrackbar("Hue Max","TrackBars",19,179,empty)
cv2.createTrackbar("Sat Min","TrackBars",110,255,empty)
cv2.createTrackbar("Sat Max","TrackBars",240,255,empty)
cv2.createTrackbar("Val Min","TrackBars",153,255,empty)
cv2.createTrackbar("Val Max","TrackBars",255,255,empty)


while True:
    img = cv2.imread(path)
    imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    # 调用回调函数,获取滑动条的值
    h_min,h_max,s_min,s_max,v_min,v_max = empty(0)
    lower = np.array([h_min,s_min,v_min])
    upper = np.array([h_max,s_max,v_max])
    # 获得指定颜色范围内的掩码
    mask = cv2.inRange(imgHSV,lower,upper)
    # 对原图图像进行按位与的操作,掩码区域保留
    imgResult = cv2.bitwise_and(img,img,mask=mask)
   
    cv2.imshow("Mask", mask)
    cv2.imshow("Result", imgResult)
    
    cv2.waitKey(1)

通过调整hsv的值,观察result即可得到想要的区间。
经过实测红色大概是 0 179 199 255 202 255

形态学处理

得到前面的HSV区间之后,我们对其mark进行处理,先进行开运算,去除小的干扰,再进行轮廓检测,再分别进行最小矩形和矩形的框选,并标注长和宽等。
代码如下:

import cv2
import numpy as np
path = 'red2.jpg'
img = cv2.imread(path)
imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
# 调用回调函数,获取滑动条的值
[h_min,h_max,s_min,s_max,v_min,v_max] = [0, 179, 199, 255, 202, 255]
lower = np.array([h_min,s_min,v_min])
upper = np.array([h_max,s_max,v_max])
# 获得指定颜色范围内的掩码
mask = cv2.inRange(imgHSV,lower,upper)
# 对原图图像进行按位与的操作,掩码区域保留
imgResult = cv2.bitwise_and(img,img,mask=mask)

#设置核
kernel = np.ones((6,6),np.uint8)
#开运算
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
font = cv2.FONT_HERSHEY_SIMPLEX
contours, hierarchy = cv2.findContours(opening,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for i in range(len(contours)):
    area = cv2.contourArea(contours[i])
    x, y, w, h = cv2.boundingRect(contours[i])
    cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
    img = cv2.putText(img, '({},{})'.format(w, h), (x, y), font, 1.2, (2, 2, 2), 2)
    rect = cv2.minAreaRect(contours[i]) #提取矩形坐标
    box = cv2.boxPoints(rect)
    box = np.int0(box)  
    angle =abs(abs(rect[2])-45) 
    length = max(rect[1])
    width = min(rect[1])
    img = cv2.putText(img, '({},{})'.format(int(length), int(width)), (np.int0(rect[0])[0], np.int0(rect[0])[1]), font, 1.2, (2, 2, 2), 2)
    cv2.drawContours(img, [box], 0, (0, 255, 0), 2)
    print(length, width, area, box)

cv2.imshow("Mask", mask)
cv2.imshow("Result", imgResult)
cv2.imshow("opening", opening)
cv2.imshow("final", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果展示

处理前

在这里插入图片描述
在这里插入图片描述

处理后

在这里插入图片描述
在这里插入图片描述


版权声明:本文为qq_40608730原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。