什么是垃圾分类ai图像识别模型(垃圾分类的正确姿势)
什么是垃圾分类ai图像识别模型(垃圾分类的正确姿势)接下来,我们进入正文,在实际去实践之前,我们很有必要来了解一下几种比较常用的颜色空间,简单总结汇总如下:从上面的结果来看,比较完全地检测到了图中出现的土地的区域,最终,我们采用外切矩形的方式完成了对其轮廓数据的确定。https://docs.opencv.org/master/d9/df8/tutorial_root.html https://docs.opencv.org/ https://www.zhihu.com/question/26881367 我们今天的内容主要是想基于OpenCV来实现对图像中我们关注的一些目标对象进行检测识别或者说是对其存在的区域位置进行挖掘,在开始这篇文章之前,我曾经看到了有人基于OpenCV实现了火焰或者是烟雾的检测,其实不管是类似的物体的检测也好不相关的物体识别检测也好,很大程度是比较通用的做法都是基于像素来完成最终的计算的。这里我们以生活中最为常
OpenCV是一款非常强大的图像处理工具,对于从事图像处理领域相关工作的人来说这个可以说是必不可少的一项工具,用起来也很方面,下吗是一段简单的介绍:
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。OpenCV用C 语言编写,它具有C ,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。
OpenCV官网是https://opencv.org/,首页截图如下所示:
下面给出来几个学习OpenCV的链接:
https://docs.opencv.org/master/d9/df8/tutorial_root.html
https://docs.opencv.org/
https://www.zhihu.com/question/26881367
我们今天的内容主要是想基于OpenCV来实现对图像中我们关注的一些目标对象进行检测识别或者说是对其存在的区域位置进行挖掘,在开始这篇文章之前,我曾经看到了有人基于OpenCV实现了火焰或者是烟雾的检测,其实不管是类似的物体的检测也好不相关的物体识别检测也好,很大程度是比较通用的做法都是基于像素来完成最终的计算的。
这里我们以生活中最为常见的土地来作为要识别检测的目标对象进行实验,先来看一张网上找到的图片,如下所示:
接下来先看一下,最终的识别检测效果:
从上面的结果来看,比较完全地检测到了图中出现的土地的区域,最终,我们采用外切矩形的方式完成了对其轮廓数据的确定。
接下来,我们进入正文,在实际去实践之前,我们很有必要来了解一下几种比较常用的颜色空间,简单总结汇总如下:
RGB颜色空间:
R:Red红色
G:Green绿色
B:Blue蓝色
HSV颜色空间:
H:Hue色度
S:Saturation饱和度
V:Value亮度
HSI颜色空间:
H:Hue色度
S:Saturation饱和度
I:Intensity强度
本质上来讲,不同的物体不同的对象自身的像素范围是不同的,在实际操作的时候基于像素区间可以过滤得到你所关注的对象,通常这样的操作会在HSV空间中进行,个人的理解是将原始的BGR或者是RGB的图像转化到HSV空间里面来确定目标对象的像素区间更为容易,我实际测试过,在RGB和BGR空间里面也是可以进行计算的,只不过不如HSV空间,这里就不再多讨论了,可以尝试别的方式,本文用的是HSV空间进行计算的。
最开始的时候去确定目标对象所处的像素空间是很笨拙的,主要是借助OpenCV和matplotlib实现的“人眼探索”,比较麻烦,后来在github社区里面找到了一个界面的实现,觉得很不错,就拿来用了,这里贴出来源码实现,如下所示:
#!usr/bin/envpython
#encoding:utf-8
from__future__importdivision
'''
功能:HSV空间图片色素范围查看器
'''
importcv2
importnumpyasnp
defnothing(x):
pass
defcolorLooker(pic='1.png'):
'''
HSV空间图片色素范围查看器
'''
#图像加载
image=cv2.imread(pic)
#窗口初始化
cv2.namedWindow('image' cv2.WINDOW_NORMAL)
#创建拖动条
#Opencv中Hue取值范围是0-179
cv2.createTrackbar('HMin' 'image' 0 179 nothing)
cv2.createTrackbar('SMin' 'image' 0 255 nothing)
cv2.createTrackbar('VMin' 'image' 0 255 nothing)
cv2.createTrackbar('HMax' 'image' 0 179 nothing)
cv2.createTrackbar('SMax' 'image' 0 255 nothing)
cv2.createTrackbar('VMax' 'image' 0 255 nothing)
#设置默认最大值
cv2.setTrackbarPos('HMax' 'image' 179)
cv2.setTrackbarPos('SMax' 'image' 255)
cv2.setTrackbarPos('VMax' 'image' 255)
#初始化设置
hMin=sMin=vMin=hMax=sMax=vMax=0
phMin=psMin=pvMin=phMax=psMax=pvMax=0
while(1):
#实时获取拖动条上的值
hMin=cv2.getTrackbarPos('HMin' 'image')
sMin=cv2.getTrackbarPos('SMin' 'image')
vMin=cv2.getTrackbarPos('VMin' 'image')
hMax=cv2.getTrackbarPos('HMax' 'image')
sMax=cv2.getTrackbarPos('SMax' 'image')
vMax=cv2.getTrackbarPos('VMax' 'image')
#设定HSV的最大和最小值
lower=np.array([hMin sMin vMin])
upper=np.array([hMax sMax vMax])
#BGR和HSV颜色空间转化处理
hsv=cv2.cvtColor(image cv2.COLOR_BGR2HSV)
mask=cv2.inRange(hsv lower upper)
result=cv2.bitwise_and(image image mask=mask)
#拖动改变阈值的同时,实时输出调整的信息
if((phMin!=hMin)|(psMin!=sMin)|(pvMin!=vMin)|(phMax!=hMax)|(psMax!=sMax)|(pvMax!=vMax)):
print("(hMin=%d sMin=%d vMin=%d) (hMax=%d sMax=%d vMax=%d)"%(hMin sMin vMin hMax sMax vMax))
phMin=hMin
psMin=sMin
pvMin=vMin
phMax=hMax
psMax=sMax
pvMax=vMax
#展示由色素带阈值范围处理过的结果图片
cv2.imshow('image' result)
ifcv2.waitKey(10)&0xFF==ord('q'):
break
cv2.destroyAllWindows()
if__name__=='__main__':
colorLooker(pic='1.png')
启动后截图如下所示:
借助界面中的拖动条可以很方便地进行调节,看到实时处理后的结果图片:
经过调节后最终的结果如下所示:
调整拖动条的同时,终端窗口输出如下所示:
到这里,我们已经获取到了所需要的各个维度的阈值数据了,就可以进行后面的处理了。
接下来我们基于上述阈值来进行区域挖掘计算,同样使用上述的图片,核心代码实现如下所示:
img=Image.open('1.png')
img=cv2.cvtColor(np.asarray(img) cv2.COLOR_RGB2BGR)
frame=cv2.cvtColor(img cv2.COLOR_BGR2HSV)
blur=cv2.GaussianBlur(frame (21 21) 0)
hsv=cv2.cvtColor(blur cv2.COLOR_BGR2HSV)
h w way=img.shape
total=h*w
print('h:' h 'w:' w 'area:' total)
#设置阈值数据
lower=[8 67 84]
upper=[85 255 255]
lower=np.array(lower dtype="uint8")
upper=np.array(upper dtype="uint8")
mask=cv2.inRange(hsv lower upper)
output=cv2.bitwise_and(hsv hsv mask=mask)
count=cv2.countNonZero(mask)
print('count:' count)
now_ratio=round(int(count)/total 3)
print('now_ratio:' now_ratio)
之后为了得到实际的轮廓区域,我们可以使用cv2.findContours方法来实现目标对象的区域挖掘计算,核心代码实现如下所示:
gray=cv2.cvtColor(output cv2.COLOR_BGR2GRAY)
print('gray_shape:' gray.shape)
ret output=cv2.threshold(gray 127 255 cv2.THRESH_BINARY)
'''
cv2.findContours:
在opencv中查找轮廓时,物体应该是白色而背景应该是黑色
contours hierarchy=cv2.findContours(image mode method)
image:输入图像
mode:轮廓的模式。cv2.RETR_EXTERNAL只检测外轮廓;cv2.RETR_LIST检测的轮廓不建立等级关系;cv2.RETR_CCOMP建立两个等级的轮廓,上一层为外边界,内层为内孔的边界。如果内孔内还有连通物体,则这个物体的边界也在顶层;cv2.RETR_TREE建立一个等级树结构的轮廓。
method:轮廓的近似方法。cv2.CHAIN_APPROX_NOME存储所有的轮廓点,相邻的两个点的像素位置差不超过1;cv2.CHAIN_APPROX_SIMPLE压缩水平方向、垂直方向、对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需要4个点来保存轮廓信息;cv2.CHAIN_APPROX_TC89_L1,cv2.CV_CHAIN_APPROX_TC89_KCOS
contours:返回的轮廓
hierarchy:每条轮廓对应的属性
'''
contours hierarchy=cv2.findContours(output cv2.RETR_EXTERNAL cv2.CHAIN_APPROX_SIMPLE)
print('contours_num:' len(contours))
count_dict={}
areas lengths=0 0
foriinrange(len(contours)):
one=contours[i]
one_lk=one.tolist()
iflen(one_lk)>=2:
area=cv2.contourArea(one)
length=cv2.arcLength(one True)
areas =area
lengths =length
left_list right_list=[O[0][0]forOinone_lk] [O[0][1]forOinone_lk]
minX maxX minY maxY=min(left_list) max(left_list) min(right_list) max(right_list)
A=abs(maxY-minY)*abs(maxX-minX)
print('area:' area 'A:' A 'length:' length)
count_dict[i]=[A area length [minX maxX minY maxY]]
sorted_list=sorted(count_dict.items() key=lambdae:e[1][0] reverse=True)
print(sorted_list[:10])
result['value']=count_dict
cv2.drawContours(img contours -1 (0 0 255) 3)
完成轮廓的挖掘计算后,我们借助于OpenCV实现可视化,结果如下所示:
可以看到:已经大体上实现了我们所要的功能,但是美中不足的是里面有很多小的矩形框,这个是我们外切矩形设计的问题,没有考虑到过滤掉嵌套或者是包含的情况,所以这里就来处理一下:
ifsorted_list:
filter_list=filterBox(sorted_list[:5])
forone_boxinfilter_list:
print('one_box:' one_box)
A area length [minX maxX minY maxY]=one_box
cv2.rectangle(img (minX maxY) (maxX minY) (0 255 0) 3)
此时的结果如下所示:
对应的计算结果输出如下所示:
('h:' 336L 'w:' 500L 'area:' 168000L)
('count:' 126387)
('now_ratio:' 0.752)
('output_shape:' (336L 500L 3L))
('gray_shape:' (336L 500L))
('contours_num:' 64)
('area:' 0.0 'A:' 2 'length:' 4.828427076339722)
('area:' 0.0 'A:' 0 'length:' 4.0)
('area:' 29.0 'A:' 44 'length:' 27.313708186149597)
('area:' 42.5 'A:' 72 'length:' 34.72792184352875)
('area:' 0.5 'A:' 6 'length:' 9.071067690849304)
('area:' 0.0 'A:' 10 'length:' 11.656854152679443)
('area:' 0.0 'A:' 1 'length:' 2.8284270763397217)
('area:' 0.0 'A:' 2 'length:' 4.828427076339722)
('area:' 1.5 'A:' 2 'length:' 5.414213538169861)
('area:' 16.5 'A:' 36 'length:' 27.55634891986847)
('area:' 5.0 'A:' 36 'length:' 37.79898953437805)
('area:' 1.5 'A:' 3 'length:' 8.242640614509583)
('area:' 0.0 'A:' 0 'length:' 2.0)
('area:' 2.0 'A:' 2 'length:' 6.0)
('area:' 360.0 'A:' 1026 'length:' 206.93607211112976)
('area:' 44.0 'A:' 143 'length:' 59.94112479686737)
('area:' 0.0 'A:' 1 'length:' 2.8284270763397217)
('area:' 0.0 'A:' 1 'length:' 2.8284270763397217)
('area:' 33.5 'A:' 60 'length:' 30.38477599620819)
('area:' 76.5 'A:' 228 'length:' 63.35533845424652)
('area:' 320.0 'A:' 792 'length:' 166.9949471950531)
('area:' 16.0 'A:' 35 'length:' 21.313708305358887)
('area:' 0.0 'A:' 8 'length:' 10.828427076339722)
('area:' 21.0 'A:' 78 'length:' 37.79898953437805)
('area:' 0.0 'A:' 1 'length:' 2.8284270763397217)
('area:' 0.0 'A:' 2 'length:' 4.828427076339722)
('area:' 0.0 'A:' 2 'length:' 4.828427076339722)
('area:' 3.5 'A:' 25 'length:' 20.727921843528748)
('area:' 1.5 'A:' 12 'length:' 13.071067690849304)
('area:' 51.0 'A:' 121 'length:' 53.94112491607666)
('area:' 0.0 'A:' 1 'length:' 2.8284270763397217)
('area:' 32.5 'A:' 50 'length:' 27.899494767189026)
('area:' 309.5 'A:' 722 'length:' 96.32590079307556)
('area:' 34.0 'A:' 42 'length:' 22.485281229019165)
('area:' 80970.5 'A:' 132699 'length:' 2718.5739262104034)
[(63 [132699 80970.5 2718.5739262104034 [1 498 67 334]]) (24 [1026 360.0 206.93607211112976 [33 60 281 319]]) (39 [792 320.0 166.9949471950531 [61 94 252 276]]) (61 [722 309.5 96.32590079307556 [384 422 75 94]]) (34 [228 76.5 63.35533845424652 [1 13 267 286]]) (25 [143 44.0 59.94112479686737 [68 81 280 291]]) (55 [121 51.0 53.94112491607666 [189 200 219 230]]) (47 [78 21.0 37.79898953437805 [100 113 235 241]]) (4 [72 42.5 34.72792184352875 [209 221 328 334]]) (32 [60 33.5 30.38477599620819 [15 25 274 280]])]
('one_box:' [132699 80970.5 2718.5739262104034 [1 498 67 334]])
为了更加直观地对比分析,我们将上面计算各个步骤中的对象数据进行可视化,借助于matplotlib绘制在同一张图上,结果如下所示:
左上角为原始图片,右下角为最终处理得到的图片,可以看到整个处理过程的变化。
到这里本文的内容就结束了,学习依旧在路上,欢迎交流,互相学习!