OpenCV自学笔记6. 图像分割
来源:互联网 发布:yum install CMake 编辑:程序博客网 时间:2024/06/04 17:44
图像分割
引言:
图像分割是图像预处理的重要步骤之一,它的主要目标是将图像划分为不同的区域,这些区域与真实世界中的物体具有一定的关联成分。图像分割的方法大体分为以下三种:基于阈值的分割、基于边缘的分割和基于区域的分割。其中基于区域的分割较为常用。OpenCV提供了 分水岭算法 和 GrabCut算法,可以快速实现图像的分割。
本小节使用的测试图像为:
————————————————————————–
使用分水岭算法进行图像分割
# -*- coding:utf-8 -*-import cv2import numpy as np# Step1. 加载图像img = cv2.imread('images/fruits.jpg')gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Step2.阈值分割,将图像分为黑白两部分ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)cv2.imshow("thresh", thresh)# Step3. 对图像进行“开运算”,先腐蚀再膨胀kernel = np.ones((3, 3), np.uint8)opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)cv2.imshow("opening", opening)# Step4. 对“开运算”的结果进行膨胀,得到大部分都是背景的区域sure_bg = cv2.dilate(opening, kernel, iterations=3)cv2.imshow("sure_bg", sure_bg)# Step5.通过distanceTransform获取前景区域dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)ret, sure_fg = cv2.threshold(dist_transform, 0.6 * dist_transform.max(), 255, 0)cv2.imshow("sure_fg", sure_fg)# Step6. sure_bg与sure_fg相减,得到既有前景又有背景的重合区域sure_fg = np.uint8(sure_fg)unknow = cv2.subtract(sure_bg, sure_fg)# Step7. 连通区域处理ret, markers = cv2.connectedComponents(sure_fg)markers = markers + 1markers[unknow==255] = 0# Step8.分水岭算法markers = cv2.watershed(img, markers)img[markers == -1] = [0, 255, 0]cv2.imshow("dst", img)cv2.waitKey(0)
各个步骤的运行结果如图:
最后的效果为:
————————————————————————–
使用GrubCut算法进行图像分割
本小节使用的测试图像为:
# -*- coding:utf-8 -*-import cv2import numpy as np# Step1. 加载图像img = cv2.imread('images/messi5.jpg')# Step2. 创建掩模、背景图和前景图mask = np.zeros(img.shape[:2], np.uint8) # 创建大小相同的掩模bgdModel = np.zeros((1,65), np.float64) # 创建背景图像fgdModel = np.zeros((1,65), np.float64) # 创建前景图像# Step3. 初始化矩形区域# 这个矩形必须完全包含前景(相当于这里的梅西)rect = (50,50,450,290)# Step4. GrubCut算法,迭代5次# mask的取值为0,1,2,3cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT) # 迭代5次# Step5. mask中,值为2和0的统一转化为0, 1和3转化为1 mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')img = img * mask2[:,:,np.newaxis] # np.newaxis 插入一个新维度,相当于将二维矩阵扩充为三维cv2.imshow("dst", img)cv2.waitKey(0)
GrubCut算法的参数如下:
注意:
Initially user draws a rectangle around the foreground region (foreground region shoule be completely inside the rectangle)
也就是说,前景图必须完全包含在矩形内,即:初始化的矩形必须完全包含梅西~
GrubCut算法的运行结果如下:
附录:用C++写的GrubCut算法小例子
参考:http://www.cnblogs.com/mikewolf2002/p/3330390.html
grubcut.cpp
#include <opencv2/opencv.hpp>#include <iostream>using namespace cv;using namespace std;int main() { string path = "images/test4.jpg"; Mat img = imread(path); // 读入图像 Mat bgModel, fgModel, mask; Rect rect; rect.x = 20; rect.y = 30; rect.width = img.cols - (rect.x << 1); rect.height = img.rows - (rect.y << 1); //rectangle(img, rect, Scalar(0, 0, 255), 3, 8, 0);//用矩形画矩形窗 //循环执行3次,这个可以自己设置 grabCut(img, mask, rect, bgModel, fgModel, 3, GC_INIT_WITH_RECT); compare(mask, GC_PR_FGD, mask, CMP_EQ); Mat foreground(img.size(), CV_8UC3, Scalar(255, 255, 255)); img.copyTo(foreground, mask); imshow("foreground", foreground); waitKey(0); return 0;}
测试用图为:
背景分割的结果如下:
可以看到,准确分割出了建筑物的主体部分
阅读全文
0 0
- OpenCV自学笔记6. 图像分割
- OpenCV学习笔记-图像分割
- OpenCV学习笔记-图像分割
- OpenCV自学笔记2:访问图像数据
- opencv学习笔记(4)----图像分割
- OpenCV自学笔记9:视频的背景分割
- opencv 图像分割
- opencv 金字塔图像分割
- opencv 金字塔图像分割
- opencv图像分割
- opencv 金字塔图像分割
- opencv 金字塔图像分割
- 基于OpenCV 图像分割
- opencv图像分割
- 【OpenCV】图像分割
- opencv 图像阈值分割图像
- [OpenCV自学笔记]Day1 如何打开一张图像
- OpenCV自学笔记12. 识别图像中的红色圆形
- Qt实现TCP文件传输例子
- iTerm2的个人使用
- 属性计算
- 理解Java内存模型总结
- 【Java基础】多线程之synchronized
- OpenCV自学笔记6. 图像分割
- struts2 result 类型
- 关于One-hot编码
- 欢迎使用CSDN-markdown编辑器
- JS return跳出方法和this属性
- JAVA观察者模式在安卓中的应用
- 【学生】SQL Server 用户登录
- 网络简单描述
- Markdown编辑器editor.md的使用