找虫子~

没错,这个项目就是来找虫子,当然是找那种很显而易见的那种,比如下图:


wenyilab

也许你说这不是明摆着一个大虫子吗,还用的着去找?

确实这个虫子是在这呢,但是要求的是用矩形框将虫子框出来,这里的难点在于虫子的触角部分很细,而右下角的logo离虫子也比较近,所以我们需要矩形既要框住虫子,又不能框住右下角的logo。

那么我们就一步一步去来解决吧~

首先我们我们需要将图片读入,转变为灰度图

#引入相关模块
import cv2
import numpy as np

img_path = "img_path"
img = cv2.imread(img_path)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

现在处理之后的效果是:


wenyilab

对该灰度图使用Sobe算子求梯度

gradx = cv2.Sobel(gray,ddepth = cv2.CV_32F,dx = 1,dy = 0)
grady = cv2.Sobel(gray,ddepth = cv2.CV_32F,dx = 0,dy = 1)
gradient = cv2.subtract(gradx,grady)

此时效果是:


wenyilab

额,sobel算子处理后的结果到底是啥,能干啥呢?
sobel算子是对图像边缘进行检测,是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度之近似值,利用快速卷积函数来提取边缘,简单有效,但其并没有将图像的主体与背景严格区分开,也就是说sobel算子没有基于图像灰度进行处理,提取的轮廓并不能令人满意(本篇的图像还是很不错的)。

在Sobel函数的第二个参数使用了cv2.CV_32F,因为opencv文档中对Sobel中的介绍中有这样的一句话:“in the case of 8-bit input images it will result in truncated derivatives”。即Sobel函数求完导数之后会有负值,而原图像是unit8(8位无符号数),所以Sobel建立的图像位数不够,会有截断,因此要使用32位有符号的数据类型,之后我们需要将上图转回原来的uint8形式。

gradient = cv2.convertScaleAbs(gradient)

效果图:


wenyilab

恩,这样看起来舒服多了,看来Sobel算子对于这张图提取的边缘信息还是很不错的。

接下来需要对上图进行高斯模糊,为后面二值化的阈值做准备

blurred = cv2.GaussianBlur(gradient,(9,9),0)

效果如下:


wenyilab

之后进行二值化和形态学处理:

(_,thresh) = cv2.threshold(blurred,90,255,cv2.THRESH_BINARY)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(15,15))
closed = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel)

效果如下:


wenyilab

cv2.threshold函数是做全局形式的阈值,将整幅图像分成了非黑即白的二值图像。
形态学处理的核心就是定义结构元素,在opencv-python中,可以使用其自带的getStructuringElement函数,也可以使用Numpy的ndarray来定义一个结构函数,在本文中使用的是python-opencv内置的常量定义椭圆(MORPH_ELLIPSE)

之后我们我们对上图进行闭运算,即先膨胀后腐蚀,如果进行开运算会将虫子触角部分截断导致不能正确框出我们想要的部分。

closed = cv2.dilate(closed,None,iterations = 4)
closed = cv2.erode(closed,None,iterations = 4)

效果图如下:


wenyilab

恩,效果还可以,接下来就是找图像的轮廓,然后画出虫子的图像了。

#找出上图的轮廓 第二个参数是检索模式,第三个参数是轮廓储存,返回轮廓本身和每个轮廓对应的属性
(_,cnts,_) = cv2.findContours(closed.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_TC89_KCOS)
c = sorted(cnts,key = cv2.contourArea,reverse = True)[0]
#取找到的最小轮廓 rect = ((center_x,center_y),(width,height),angle)
rect = cv2.minAreaRect(c)
#将rect变为整数
box = np.int0(cv2.boxPoints(rect))
#画出轮廓
draw_img = cv2.drawContours(img.copy(),[box],-1,(0,0,255),3)
cv2.imshow("draw_img",draw_img)
cv2.waitKey(0)
cv2.destoryAllWindows()

最终效果如下:


wenyilab

完美~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容