Opencv项目实战:22 物体颜色识别并框选

news/2025/2/12 10:41:46/

目录

0、项目介绍

1、效果展示

2、项目搭建

3、项目代码展示与部分讲解

Color_trackbar.py

bgr_detector.py

test.py

4、项目资源

5、项目总结


0、项目介绍

本次项目要完成的是对物体颜色的识别并框选,有如下功能:

(1)准确对颜色进行较大范围框选,统一使用绿色边界框显示。

(2)识别物体内部的颜色边缘轮廓,以白色为边缘,对物体的框选更加细致。

(3)可以对自己感兴趣的颜色进行识别选择,不想要的颜色不会被识别。

(4)在窗口中的边框旁打印上颜色对应的英文字母。

(5)如果发现效果不是很好,请耐心调试Color_trackbar.py文件。

1、效果展示

2、项目搭建

——22 Color box identification——bgr_detector.py——Color_trackbar.py——test.py

按照如上所示,新建文件即可。

3、项目代码展示与部分讲解

这里我来讲解一下,这三个文件该怎么用,我这里就少讲原理了。(写着有点累,我想大家应该有这个能力看懂这个代码)。

Color_trackbar.py

import cv2
import numpy as np
from bgr_detector import BGR,emptypath = 'test.png'cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars",640,250)
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)bgr = BGR(img)#图像转化为HSV格式,H:色调S:饱和度V:明度imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)#获取轨迹栏位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)#创建一个蒙版,提取需要的颜色为白色,不需要的颜色为白色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)imgStack = bgr.stackImages(0.5,([img,imgHSV],[mask,imgResult]))#定义比例尺cv2.imshow("Stacked Images", imgStack)if cv2.waitKey(1) & 0xFF == 27:break

运行此文件,test.png文件为你需要检测的物体照片,这里我用的是以前的一个素材,你自行替换掉你需要识别的物体照片即可。

它会弹出这样的界面,你只需要自己不断的去拖拽左边的轨迹栏,然后将你想要识别的颜色单独识别出来即可,在下方的控制面板中,将里面的内容复制一行,记住是你成功识别后的内容。

如果你调来调去,效果不是很好,请你耐心一点,当然根据我的检测,使用你想要识别物体的照片,对后面的识别效果越好。

bgr_detector.py

import cv2
import numpy as npclass BGR():def __init__(self,img,scale=0.7):self.img=imgself.scale=scaleself.imgResult=img.copy()self.myColors = [[5, 107, 0, 19, 255, 255],[57, 76, 0, 100, 255, 255],[95, 78, 202, 128, 255, 255]]self.myColorValues = [[51, 153, 255],  ## BGR[0, 255, 0],    # https://www.rapidtables.org/zh-CN/web/color/RGB_Color.html[255, 0, 0]]self.objectColor=["Orange","Green","Blue"]def stackImages(self,scale,imgArray):rows = len(imgArray)cols = len(imgArray[0])rowsAvailable = isinstance(imgArray[0], list)width = imgArray[0][0].shape[1]height = imgArray[0][0].shape[0]if rowsAvailable:for x in range ( 0, rows):for y in range(0, cols):if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, self.scale, self.scale)else:imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, self.scale, self.scale)if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)imageBlank = np.zeros((height, width, 3), np.uint8)hor = [imageBlank]*rowshor_con = [imageBlank]*rowsfor x in range(0, rows):hor[x] = np.hstack(imgArray[x])ver = np.vstack(hor)else:for x in range(0, rows):if imgArray[x].shape[:2] == imgArray[0].shape[:2]:imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)else:imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)hor= np.hstack(imgArray)ver = horreturn verdef getContours(self,img, minArea=500):contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)x, y, w, h = 0, 0, 0, 0for cnt in contours:area = cv2.contourArea(cnt)if area > minArea:cv2.drawContours(self.imgResult, cnt, -1, (255, 255, 255), 3)peri = cv2.arcLength(cnt, True)approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)x, y, w, h = cv2.boundingRect(approx)cv2.rectangle(self.imgResult, (x, y), (x + w, y + h), (0, 255, 0), 2)return x + w // 2, y,w,hdef findColor(self,img):imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)count = 0for color in self.myColors:lower = np.array(color[0:3])upper = np.array(color[3:6])mask = cv2.inRange(imgHSV, lower, upper)x,y,w,h=self.getContours(mask)cv2.putText(self.imgResult, self.objectColor[count],(x + (w // 2) - 10, y + (h // 2) - 10), cv2.FONT_HERSHEY_COMPLEX, 0.7,(0, 0, 255), 2)count += 1return self.imgResultdef empty(ways):pass

此文件无需运行,这是一个类文件,你需要修改的地方在初始化中,将之前你复制的内容粘贴到self.myColors的列表中,然后在self.myColorValues的旁边有一个注释,内容为一个RGB网址,点击进入。记住,在上面是你想要的颜色,下面的BGR就是什么颜色。

这里的值是RGB值,你需要自己改成BGR值。

为了有些同学还是不能理解我的意思,你可以看看这里我给的注释。

self.myColors=[[橙色的HSV值],

                        [紫色的HSV值],

                        [绿色的HSV值],

                        [蓝色的HSV值]]

self.myColorValues=[[橙色的BGR值],

                                [紫色的BGR值],

                                [绿色的BGR值],

                                [蓝色的BGR值]]  #网址中获得的是RGB值,手动改为BGR.

self.objectColor=["Orange","Purple","Green","Blue"] #按顺序来.

以上就是你需要修改的地方,很详细了。

test.py

import cv2
import numpy as np
from bgr_detector import BGRframeWidth = 640
frameHeight = 480
cap = cv2.VideoCapture(0)
cap.set(3, frameWidth)
cap.set(4, frameHeight)
cap.set(10,150)myPoints =  []  ## [x , y , colorId ]while True:success, img = cap.read()bgr = BGR(img)imgResult=bgr.findColor(img)imgStack = bgr.stackImages(0.8, ([img, imgResult]))cv2.imshow("Result", imgStack)if cv2.waitKey(1) & 0xFF == 27:break

这里就是你的测试文件,可以看到代码行数很少,这就是使用类文件的好处。

4、项目资源

GitHub:22 物体颜色识别并框选

5、项目总结

我觉得本次项目挺有意思的,说实话项目22本来不是颜色识别的,这个是我室友他的项目上需要完成这样一个功能,然后我就花了一下午帮他做了做,效果的实现非常不错,用在比较单一背景下的物体追踪识别什么的,挺有研究意义的。最开始我还参考过其他博主对于RGB颜色的识别和框选,效果什么的我感觉不是很好,而且他们使用的方法与我最初想的一种思路有很大的接近,即是对某一感兴趣的颜色,将其临近的RGB值考虑到,实际上不是很靠谱,因为我们不知道三个值(‘R’、‘G’、‘B’)的组合会出现什么颜色,细微的改变可能变化肉眼是看不出来的,红色还是红色,像之前考虑的临近值,颜色可能是粉色或紫色,而你还是识别的红色。当然在我这里,我用到的方法是用HSV值来进行颜色检测,采用轨迹栏作为调色板,进行颜色的提取,然后将其对应的BGR值打印出来,有选择性。

偷偷给你们说一句,不要用黑色,识别时将我的头发识别的框和文字到处都是,巨搞笑。

还有一点就是,我发现环境的亮度对于颜色的识别也是有一点点的影响的。


http://www.ppmy.cn/news/32557.html

相关文章

JavaWeb学习-JSP

JSP作用 JSP全称为Java Server Pages即Java服务器页面,主要作用是代替Servlet程序回传HTML页面的数据,因为Servlet程序回传HTML页面数据非常繁琐,开发成本和维护成本较高。 package com.pero.jsp.jsp_javaweb;import jakarta.servlet.*; im…

C++模拟实现红黑树

目录 介绍----什么是红黑树 甲鱼的臀部----规定 分析思考 绘图解析代码实现 节点部分 插入部分分步解析 ●父亲在祖父的左,叔叔在祖父的右: ●父亲在祖父的右,叔叔在祖父的左: 测试部分 整体代码 介绍----什么是红黑树 红…

IDEA安装JRebel实现热部署,自动reload和recompile

利用JRebel插件实现代码及时编译功能,帮助我们在开发过程中节省项目重启时间,提高开发效率。JRebel插件实现及时编译,帮助我们在开发过程中节省项目重启时间,提高开发效率。一、安装插件安装流程:1.下载安装JRebel插件…

好记性不如烂笔头(2)

概述:用来记录一些小技巧。 1.查看MyBatis执行的sql 类:org.apache.ibatis.mapping.MappedStatement方法:getBoundSql(Object parameterObject)在IDEA的Evaluate Expression查看sql:boundSql.getSql() 2.maven仓库地址为https&…

解决 IDA 防F5转伪C笔记

某app砸壳后放到IDA,根据堆栈查到该位置如下; G调到,0x1b81bcc 看下: BR 调到后面 x8 x9地址,汇编指令; 找到x9的地址,然后减去基地址也就是首地址,得到便宜地址; hook x9: var moduleAddr = Module.findBaseAddress("XX"); var line = moduleAddr.add

面试重难点问题(C++)

持续更新!!!!! 网络部分 1.问,四次挥手的过程,和双方状态变化? 挥手这前,两边都是established状态,客户端发起断开请求,向服务器发送fin请求&…

单调栈——图文详解(附JavaCode模板)

🍏🍐🍊🍑🍒🍓🫐🥑🍋🍉🥝 啥是"单调栈",它能解决什么样的问题? 文章目录🦩单调栈的概念&a…

【C++进阶】四、使用红黑树对set和map进行封装(四)

目录 前言 一、改造红黑树 1.1 红黑树迭代器相关 1.2 红黑树接口相关 二、set代码 三、map代码 前言 set 是 K模型的容器,map 是 KV模型的容器,但是它们的底层实现都是红黑树实现,即用红黑树可以封装出 set和 map,之前的篇章…