学习记录技术分享小站

使用OpenCV滤色后查找指定颜色的矩形

使用opencv查找特定颜色的矩形

首先需求是:一个名为draw_rect(pic),将传过来的图片对象,根据设定的颜色范围,画出这个颜色范围内图片中存在的最大矩形,并将矩形在图片中的x,y坐标,矩形的大小w,h返回
比如,我是想将jx3中科举界面的矩形画出,然后根据比例计算出问题所在的位置

获取科举界面HSV颜色值,该程序实现点击图片输出RGB/HSV值

# coding=utf-8
import cv2

# 读取图片并缩放
img = cv2.imread('test.jpg')
height, width = img.shape[:2]
size = (int(width/2), int(height/2))
# 缩放
img = cv2.resize(img, size, interpolation=cv2.INTER_AREA)
# BGR转化为HSV
HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 鼠标点击响应事件
def getposHsv(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        print("HSV is", HSV[y, x])

def getposBgr(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        print("Bgr is", img[y, x])

cv2.imshow("imageHSV", HSV)
cv2.imshow('image', img)
cv2.setMouseCallback("imageHSV", getposHsv)
cv2.setMouseCallback("image", getposBgr)
cv2.waitKey(0)

结果如下:

根据得到的HSV值设定颜色范围,并将待识别图片转为HSV格式

def draw_rect(pic):
    # 颜色范围,这里我设置±10
    lower = (16, 8, 206)
    upper = (36, 28, 226)
    img = cv2.imread(pic)
    # 图片转成HSV格式
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

根据设定好的颜色范围调用OpenCV的 inRange 函数

mask = cv2.inRange(hsv, lower, upper)
cv2.imshow('Mask', mask)

可以看到其他的颜色都被去除了,但需要注意的是,如果用户使用Win7系统,并且主题设置为经典主题,会导致软件的背景色和科举界面的背景色过于接近,没能去除。但科举界面比软件界面大,因此选出最大的矩形即可解决。不过在此之前,我们还是需要填充中心、去除噪声

填充中心和去噪

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25))
# 填充中心
closed = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
# 执行50次形态学腐蚀与膨胀
closed = cv2.erode(closed, None, iterations=50)
closed = cv2.dilate(closed, None, iterations=50)
cv2.imshow('closed', closed)


可以看到,只剩下两个矩形了,那么接下来寻找轮廓并画出就可以了

寻找轮廓并画出矩形

# 寻找轮廓
contours, hierarchy = cv2.findContours(
    closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 绘制轮廓
allResult = cv2.drawContours(img.copy(), contours, -1, (0, 0, 255), 2)
cv2.imshow('Allresult',allResult)

至此,就大概完成了。矩形的信息存在 contours 中,但我是要画出最大的矩形,并且返回x,y,w,h<

找出最大的矩形,并返回x,y,w,h

length = len(contours)
    print(length)
    # 如果长度为0,说明不存在,返回0,0,0,0
    if length == 0:
        x, y, w, h = 0, 0, 0, 0
    else:
        # 新建5个变量,存储最大矩形的面积,x,y,w,h
        max_rectangle = 0
        max_rectangle_x, max_rectangle_y, max_rectangle_w, max_rectangle_h = 0, 0, 0, 0
        # 如果存在多个,则去最大的一个
        for i in range(0, length):
            x, y, w, h = cv2.boundingRect(contours&amp;#91;i])
            if w * h &amp;amp;gt; max_rectangle:                
                max_rectangle = w * h
                max_rectangle_x = x
                max_rectangle_y = y
                max_rectangle_w = w
                max_rectangle_h = h
        x, y, w, h = max_rectangle_x, max_rectangle_y, max_rectangle_w, max_rectangle_h
        # 得到最大的矩形后,根据比例计算出科举问题的位置
        cv2.rectangle(img, (x + int(w * pic_ratio&amp;#91;0]), y + int(h * pic_ratio&amp;#91;1])), (x + int(w * pic_ratio&amp;#91;2]), y + int(h * pic_ratio&amp;#91;3])), (0, 0, 255), 2)
        # # 显示结果
        cv2.imshow("result", img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    return (x, y, w, h);

可以看到,正好框柱了问题,至此,本文结束

使用OpenCV滤色后查找指定颜色的矩形

https://www.yuliu.tech/archives/156/

作者

羽流

发布时间

2020-02-12

许可协议

CC BY-SA 4.0

添加新评论