Python中的图像处理(第十四章)Python图像分割(3)

Python中的图像处理(第十四章)Python图像分割(3)

前言

随着人工智能研究的不断兴起,Python的应用也在不断上升,由于Python语言的简洁性、易读性以及可扩展性,特别是在开源工具和深度学习方向中各种神经网络的应用,使得Python已经成为最受欢迎的程序设计语言之一。由于完全开源,加上简单易学、易读、易维护、以及其可移植性、解释性、可扩展性、可扩充性、可嵌入性:丰富的库等等,自己在学习与工作中也时常接触到Python,这个系列文章的话主要就是介绍一些在Python中常用一些例程进行仿真演示!

本系列文章主要参考杨秀章老师分享的代码资源,杨老师博客主页是Eastmount,杨老师兴趣广泛,不愧是令人膜拜的大佬,他过成了我理想中的样子,希望以后有机会可以向他请教学习交流。

因为自己是做图像语音出身的,所以结合《Python中的图像处理》,学习一下Python相关,OpenCV已经在Python上进行了多个版本的维护,所以相比VS,Python的环境配置相对简单,缺什么库直接安装即可。本系列文章例程都是基于Python3.8的环境下进行,所以大家在进行借鉴的时候建议最好在3.8.0版本以上进行仿真。本文继续来对本书第十四章的后4个例程进行介绍。

一. Python准备

如何确定自己安装好了python

win+R输入cmd进入命令行程序
在这里插入图片描述
点击“确定”
在这里插入图片描述
输入:python,回车
在这里插入图片描述
看到Python相关的版本信息,说明Python安装成功。

二. Python仿真

(1)新建一个chapter14_11.py文件,输入以下代码,图片也放在与.py文件同级文件夹下

# coding: utf-8
# 2021-05-17 Eastmount CSDN
import numpy as np
import cv2
from matplotlib import pyplot as plt

#读取原始图像
img = cv2.imread('test01.png')

#图像灰度化处理
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#图像阈值化处理
ret, thresh = cv2.threshold(gray, 0, 255,
                            cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

#图像开运算消除噪声
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

#图像膨胀操作确定背景区域
sure_bg = cv2.dilate(opening,kernel,iterations=3)

#距离运算确定前景区域
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)

#寻找未知区域
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)

#标记变量
ret, markers = cv2.connectedComponents(sure_fg)

#所有标签加一,以确保背景不是0而是1
markers = markers+1

#用0标记未知区域
markers[unknown==255]=0

#分水岭算法实现图像分割
markers = cv2.watershed(img, markers)
img[markers == -1] = [255,0,0]

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图像
titles = [u'标记区域', u'图像分割']  
images = [markers, img]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()

保存.py文件
输入eixt()退出python,输入命令行进入工程文件目录
在这里插入图片描述
输入以下命令,跑起工程

python chapter14_11.py

在这里插入图片描述
没有报错,直接弹出图片,运行成功!
在这里插入图片描述

(2)新建一个chapter14_12.py文件,输入以下代码,图片也放在与.py文件同级文件夹下

#coding:utf-8
# 2021-05-17 Eastmount CSDN
import cv2
import numpy as np

#读取原始图像
img = cv2.imread('test.png')

#获取图像行和列
rows, cols = img.shape[:2]

#目标图像
dst = img.copy()

#mask必须行和列都加2且必须为uint8单通道阵列
#mask多出来的2可以保证扫描的边界上的像素都会被处理
mask = np.zeros([rows+2, cols+2], np.uint8)  

#图像漫水填充处理
#种子点位置(30,30) 设置颜色(0,255,255) 连通区范围设定loDiff upDiff
#src(seed.x, seed.y) - loDiff <= src(x, y) <= src(seed.x, seed.y) +upDiff
cv2.floodFill(dst, mask, (30, 30), (0, 255, 255),
              (100, 100, 100), (50, 50, 50),
              cv2.FLOODFILL_FIXED_RANGE)

#显示图像
cv2.imshow('src', img)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

保存.py文件输入以下命令,跑起工程

python chapter14_12.py

在这里插入图片描述

没有报错,直接弹出图片,运行成功!
在这里插入图片描述
在这里插入图片描述

(3)新建一个chapter14_13.py文件,输入以下代码,图片也放在与.py文件同级文件夹下

# coding:utf-8
# 2021-05-17 Eastmount CSDN
import cv2
import random
import sys
import numpy as np

#使用说明 点击鼠标选择种子点
help_message = '''USAGE: floodfill.py [<image>]
Click on the image to set seed point
Keys:
  f - toggle floating range
  c - toggle 4/8 connectivity
  ESC - exit
'''
 
if __name__ == '__main__':

    #输出提示文本
    print(help_message)

    #读取原始图像
    img = cv2.imread('test01.png')

    #获取图像高和宽
    h, w = img.shape[:2]

    #设置掩码 长和宽都比输入图像多两个像素点 
    mask = np.zeros((h+2, w+2), np.uint8)

    #设置种子节点和4邻接
    seed_pt = None
    fixed_range = True
    connectivity = 4 

    #图像漫水填充分割更新函数
    def update(dummy=None):
        if seed_pt is None:
            cv2.imshow('floodfill', img)
            return
        
        #建立图像副本并漫水填充
        flooded = img.copy()
        mask[:] = 0 #掩码初始为全0
        lo = cv2.getTrackbarPos('lo', 'floodfill') #观察点像素邻域负差最大值
        hi = cv2.getTrackbarPos('hi', 'floodfill') #观察点像素邻域正差最大值
        print('lo=', lo, 'hi=', hi)

        #低位比特包含连通值 4 (缺省)8
        flags = connectivity
        
        #考虑当前象素与种子象素之间的差(高比特也可以为0if fixed_range:
            flags |= cv2.FLOODFILL_FIXED_RANGE
            
        #以白色进行漫水填充
        cv2.floodFill(flooded, mask, seed_pt,
                      (random.randint(0,255), random.randint(0,255),
                       random.randint(0,255)), (lo,)*3, (hi,)*3, flags)

        #选定基准点用红色圆点标出
        cv2.circle(flooded, seed_pt, 2, (0, 0, 255), -1)
        print("send_pt=", seed_pt)

        #显示图像
        cv2.imshow('floodfill', flooded)

    #鼠标响应函数
    def onmouse(event, x, y, flags, param):
        global seed_pt #基准点

        #鼠标左键响应选择漫水填充基准点
        if flags & cv2.EVENT_FLAG_LBUTTON:
            seed_pt = x, y
            update()

    #执行图像漫水填充分割更新操作
    update()
    
    #鼠标更新操作
    cv2.setMouseCallback('floodfill', onmouse)

    #设置进度条
    cv2.createTrackbar('lo', 'floodfill', 20, 255, update)
    cv2.createTrackbar('hi', 'floodfill', 20, 255, update)

    #按键响应操作
    while True:
        ch = 0xFF & cv2.waitKey()
        #退出
        if ch == 27:
            break
        #选定时flags的高位比特位0
        #此时邻域的选定为当前像素与相邻像素的差, 联通区域会很大
        if ch == ord('f'):
            fixed_range = not fixed_range 
            print('using %s range' % ('floating', 'fixed')[fixed_range])
            update()
        #选择4方向或则8方向种子扩散
        if ch == ord('c'):
            connectivity = 12-connectivity 
            print('connectivity =', connectivity)
            update()
    cv2.destroyAllWindows()             

保存.py文件输入以下命令,跑起工程

python chapter14_13.py

在这里插入图片描述

没有报错,直接弹出图片,运行成功!
在这里插入图片描述
点击图像选择基准点,滑动参数即可进行分割(退出有待完善)。

(4)新建一个chapter14_14.py文件,输入以下代码,图片也放在与.py文件同级文件夹下

# coding:utf8
# 2021-05-17 Eastmount CSDN
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取原始图像
img = cv2.imread("word.png" )

#中值滤波去除噪声
median = cv2.medianBlur(img, 3)

#转换成灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#Sobel算子锐化处理
sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize = 3)

#图像二值化处理
ret, binary = cv2.threshold(sobel, 0, 255,
                            cv2.THRESH_OTSU+cv2.THRESH_BINARY)

#膨胀和腐蚀处理
#设置膨胀和腐蚀操作的核函数
element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 9))
element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (24, 6))

#膨胀突出轮廓
dilation = cv2.dilate(binary, element2, iterations = 1)

#腐蚀去掉细节
erosion = cv2.erode(dilation, element1, iterations = 1)

#查找文字轮廓
region = []
contours, hierarchy = cv2.findContours(erosion,
                                       cv2.RETR_TREE,
                                       cv2.CHAIN_APPROX_SIMPLE)

#筛选面积
for i in range(len(contours)):
    #遍历所有轮廓
    cnt = contours[i]
    
    #计算轮廓面积
    area = cv2.contourArea(cnt) 
    
    #寻找最小矩形
    rect = cv2.minAreaRect(cnt)

    #轮廓的四个点坐标
    box = cv2.boxPoints(rect)
    box = np.int0(box)

    # 计算高和宽
    height = abs(box[0][1] - box[2][1])
    width = abs(box[0][0] - box[2][0])

    #过滤太细矩形
    if(height > width * 1.5): 
        continue

    region.append(box)
   
#定位的文字用绿线绘制轮廓
for box in region:
    print(box)
    cv2.drawContours(img, [box], 0, (0, 255, 0), 2)

#显示图像
cv2.imshow('Median Blur', median)
cv2.imshow('Gray Image', gray)
cv2.imshow('Sobel Image', sobel)
cv2.imshow('Binary Image', binary)
cv2.imshow('Dilation Image', dilation)
cv2.imshow('Erosion Image', erosion)
cv2.imshow('Result Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

保存.py文件输入以下命令,跑起工程

python chapter14_14.py

在这里插入图片描述
没有报错,直接弹出图片,运行成功!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三. 小结

本文主要介绍在Python中调用OpenCV库对图像进行分割,包括分水岭算法,种子填充,漫水填充等。由于本书的介绍比较系统全面,所以会出一个系列文章进行全系列仿真实现,感兴趣的还是建议去原书第十四章深入学习理解,下一篇文章将继续介绍第十五章节的5例仿真实例。每天学一个Python小知识,大家一起来学习进步阿!

本系列示例主要参考杨老师GitHub源码,安利一下地址:ImageProcessing-Python(喜欢记得给个star哈!)

猜你喜欢

转载自blog.csdn.net/sinat_34897952/article/details/124905673
今日推荐