(三)OpenCV图像分割python版0 环境
Ubuntu18.04
Python3.6
OpenCV3.2.0
引⼊opencv
import cv2
1 基于阈值
1.0 ⼩序
灰度阈值化,简单,速度快,⼴泛应⽤于硬件图像处理,如FPGA实时图像处理.
1.2 适⽤场景
图⽚中各物体不接触,且物体和背景的灰度值差别较明显,灰度阈值处理效果较好;
waterShed算法
def waterShed(sourceDir):
# 读取图⽚
img = cv2.imread(sourceDir)
# 原图灰度处理,输出单通道图⽚
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ⼆值化处理Otsu算法
reval_O, dst_Otsu = cv2.threshold(gray,0,255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU) # ⼆值化处理Triangle算法
reval_T, dst_Tri = cv2.threshold(gray,0,255, cv2.THRESH_BINARY_INV | cv2.THRESH_TRIANGLE) # 滑动窗⼝尺⼨
kernel = np.ones((3,3), np.uint8)
unknown怎么处理# 形态学处理:开处理,膨胀边缘
opening = phologyEx(dst_Tri, cv2.MORPH_OPEN, kernel, iterations=2)
# 膨胀处理背景区域
dilate_bg = cv2.dilate(opening, kernel, iterations=3)
# 计算开处理图像到邻域⾮零像素距离
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2,5)
# 正则处理
norm = alize(dist_transform,0,255, cv2.NORM_MINMAX)
# 阈值处理距离图像,获取图像前景图
retval_D, dst_fg = cv2.threshold(dist_transform,0.5*dist_transform.max(),255,0)
# 前景图格式转换
dst_fg = np.uint8(dst_fg)
# 未知区域计算:背景减去前景
unknown = cv2.subtract(dilate_bg, dst_fg)
cv2.imshow("Difference value", unknown)
cv2.imwrite('./images/saved/unknown_reginon.png', unknown)
# 处理连接区域
retval_C, marks = tedComponents(dst_fg)
cv2.imshow('Connect marks', marks)
cv2.imwrite('./images/saved/connect_marks.png', marks)
# 处理掩模
marks = marks +1
marks[unknown==255]=0
cv2.imshow("marks undown", marks)
# 分⽔岭算法分割
marks = cv2.watershed(img, marks)
# 绘制分割线
img[marks ==-1]=[255,0,255]
cv2.imshow("Watershed", img)
cv2.imwrite('./images/saved/watershed.png', img)
cv2.waitKey(0)
sourceDir ="./images/reading/water_coins.jpg"
waterShed(sourceDir)
背景图和前景图.
图1.0 ⿊⾊部分背景图(左)⽩⾊部分前景图(右)未知区域和分割图.
图1.2 未知区域(左)分割图(右)
2 基于边缘
边缘检测的结果是点,不能作为图像分割结果,需要进⼀步处理,将边缘点沿着图形边界连接,形成边缘链.
检测算⼦:
Sobel,Laplace, Canny
寻轮廓:
findContours
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ⾼斯模糊处理:去噪(效果最好)
blur = cv2.GaussianBlur(gray,(9,9),0)
# Sobel计算XY⽅向梯度
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)
# 绝对值
gradient = vertScaleAbs(gradient)
# ⾼斯模糊处理:去噪(效果最好)
blured = cv2.GaussianBlur(gradient,(9,9),0)
# ⼆值化
_ , dst = cv2.threshold(blured,90,255, cv2.THRESH_BINARY)
# 滑动窗⼝
kernel = StructuringElement(cv2.MORPH_ELLIPSE,(107,76))
# 形态学处理:形态闭处理(腐蚀)
closed = phologyEx(dst, cv2.MORPH_CLOSE, kernel)
# 腐蚀与膨胀迭代
closed = de(closed,None, iterations=4)
closed = cv2.dilate(closed,None, iterations=4)
# 获取轮廓
_, cnts, _ = cv2.py(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) c =sorted(cnts, urArea, reverse=True)[0]
rect = cv2.minAreaRect(c)
box = np.int0(cv2.boxPoints(rect))
draw_img = cv2.py(),[box],-1,(0,0,255),3)
cv2.imshow("Box", draw_img)
cv2.imwrite('./images/saved/monkey.png', draw_img)
cv2.waitKey(0)
sourceDir ="./images/reading/monkey1.jpg"
cutImage(sourceDir)
原图与结果图.
图2.1 原图(左)结果图(右) 3 基于区域
grabCut算法
img_x = img.shape[1]
# 图⽚⾼度
img_y = img.shape[0]
# 分割的矩形区域
rect =(96,1,359,358)
# 背景模式,必须为1⾏,13x5列
bgModel = np.zeros((1,65), np.float64)
# 前景模式,必须为1⾏,13x5列
fgModel = np.zeros((1,65), np.float64)
# 图像掩模,取值有0,1,2,3
mask = np.zeros(img.shape[:2], np.uint8)
# grabCut处理,GC_INIT_WITH_RECT模式
# grabCut处理,GC_INIT_WITH_MASK模式
# abCut(img, mask, rect, bgModel, fgModel, 4, cv2.GC_INIT_WITH_MASK)
# 将背景0,2设成0,其余设成1
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
# 重新计算图像着⾊,对应元素相乘
img = img*mask2[:,:, np.newaxis]
cv2.imshow("Result", img)
cv2.waitKey(0)
sourceDir ="./images/reading/bird2.png"
grab_cut(sourceDir)
原图与结果图
图3 原图(左) 结果图(右)
4 问题
grabCut(img, mask, rect, bgModel, fgModel, iterCount, cv2.GC_INIT_WITH_MASK)
OpenCV Error: Assertion failed (!pty() && !pty()) in initGMMs, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/imgpro c/src/grabcut.cpp, line 379
<: /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/imgproc/src/grabcut.cpp:379: error: (-215) !pty() && !pty() in fu nction initGMMs
grabCut不能使⽤GC_INIT_WITH_MASK切割图⽚,我也佷⽆奈.
5 总结
还在学习阶段,该篇为笔记记录,借鉴较多.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论