第十七篇【传奇开心果系列】Python的OpenCV库技术点案例示例:自适应阈值二值化处理图像提取文字_python图像边缘提取二值化(1)

image = cv2.imread(‘your_image.jpg’, 0)

自适应阈值二值化

binary = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)

查找轮廓

contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

绘制轮廓

contour_image = cv2.drawContours(image.copy(), contours, -1, (0, 255, 0), 2)

显示结果

cv2.imshow(‘Binary Image’, binary)
cv2.imshow(‘Contour Image’, contour_image)
cv2.waitKey(0)
cv2.destroyAllWindows()


在上述代码中,首先使用`cv2.adaptiveThreshold`函数对图像进行自适应阈值二值化,其中`cv2.ADAPTIVE_THRESH_MEAN_C`表示使用局部均值作为阈值计算方式。然后使用`cv2.findContours`函数查找图像中的轮廓,并使用`cv2.drawContours`函数绘制轮廓。


您可以根据实际情况调整自适应阈值二值化的参数,如窗口大小和均值计算方法,以获得最佳的结果。


### 二、扩展思路介绍


![在这里插入图片描述](https://img-blog.csdnimg.cn/1e7a3352201449569c41ca95166e02de.jpg)当使用自适应阈值二值化来处理图像时,还可以考虑以下几个方面的扩展:


1. 调整自适应阈值二值化的参数:除了示例代码中使用的`cv2.ADAPTIVE_THRESH_MEAN_C`方法外,还可以尝试使用`cv2.ADAPTIVE_THRESH_GAUSSIAN_C`方法,它使用局部区域的加权和作为阈值计算方式。可以根据图像的特点和需求,比较两种方法的效果并选择最佳的方法。
2. 对二值化图像进行形态学操作:在获取到二值化图像后,可以应用形态学操作来进一步处理图像,以改善文字轮廓的提取效果。例如,可以使用`cv2.dilate`函数对二值化图像进行膨胀操作,以填充文字内部的空洞;或者使用`cv2.erode`函数对二值化图像进行腐蚀操作,以去除细小的噪点。
3. 使用轮廓特征进行筛选:在查找轮廓后,可以通过一些条件来筛选出符合要求的轮廓。例如,可以根据轮廓的面积、周长、宽高比等特征进行筛选,以排除不需要的轮廓。
4. 应用其他图像处理技术:如果仍然无法满足需求,可以尝试其他图像处理技术来提取文字轮廓。例如,可以使用边缘检测算法(如Canny边缘检测)来获取文字的边缘信息;或者使用图像分割算法(如基于区域的分割算法)将图像分割为文字和背景区域。


综上所述,根据具体的需求和图像特点,可以尝试调整参数、应用形态学操作、筛选轮廓以及使用其他图像处理技术来进一步优化文字轮廓的提取效果。


### 三、调整自适应阈值二值化的参数示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/3dfc94a3644e4667bb6e7e47e354f144.jpg)下面是一个示例代码,演示了如何调整自适应阈值二值化的参数来提取文字轮廓:



import cv2

读取图像

image = cv2.imread(‘your_image.jpg’, 0)

自适应阈值二值化(调整参数)

binary = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 5)

查找轮廓

contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

绘制轮廓

contour_image = cv2.drawContours(image.copy(), contours, -1, (0, 255, 0), 2)

显示结果

cv2.imshow(‘Binary Image’, binary)
cv2.imshow(‘Contour Image’, contour_image)
cv2.waitKey(0)
cv2.destroyAllWindows()


在上述代码中,我调整了自适应阈值二值化的两个参数:窗口大小(11)和均值计算的偏移值(5)。您可以根据实际需求,尝试不同的参数值来获得最佳的效果。


增大窗口大小可以考虑更大范围的像素值,从而适应不同大小的文字。减小偏移值可以使阈值更接近局部像素均值,以更好地区分文字和背景。


请注意,调整参数时需要根据具体情况进行实验和调整。不同的图像和文字特征可能需要不同的参数设置。


### 四、对二值化图像进行形态学操作示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/0c7d795311194c379881c2540428c598.jpg)下面是一个示例代码,演示了如何对二值化图像进行形态学操作来改善文字轮廓的提取效果:



import cv2
import numpy as np

读取图像

image = cv2.imread(‘your_image.jpg’, 0)

自适应阈值二值化

binary = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)

形态学操作(膨胀和腐蚀)

kernel = np.ones((3, 3), np.uint8)
dilated = cv2.dilate(binary, kernel, iterations=1)
eroded = cv2.erode(dilated, kernel, iterations=1)

查找轮廓

contours, _ = cv2.findContours(eroded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

绘制轮廓

contour_image = cv2.drawContours(image.copy(), contours, -1, (0, 255, 0), 2)

显示结果

cv2.imshow(‘Binary Image’, binary)
cv2.imshow(‘Dilated Image’, dilated)
cv2.imshow(‘Eroded Image’, eroded)
cv2.imshow(‘Contour Image’, contour_image)
cv2.waitKey(0)
cv2.destroyAllWindows()


在上述代码中,我使用了两种形态学操作:膨胀(dilate)和腐蚀(erode)。首先,使用`cv2.dilate`函数对二值化图像进行膨胀操作,以填充文字内部的空洞和连接断开的部分。然后,使用`cv2.erode`函数对膨胀后的图像进行腐蚀操作,以去除细小的噪点。


通过应用形态学操作,可以进一步改善文字轮廓的连通性和完整性,使得提取效果更好。


请注意,形态学操作的参数(如核大小、迭代次数)也可以根据实际情况进行调整,以获得最佳的效果。


### 五、使用轮廓特征进行筛选示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/175cd37be8fd487f914976ee6df980a4.jpg)下面是一个示例代码,演示了如何使用轮廓特征进行筛选,以提取符合要求的文字轮廓:



import cv2

读取图像

image = cv2.imread(‘your_image.jpg’, 0)

自适应阈值二值化

binary = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)

查找轮廓

contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

筛选轮廓

filtered_contours = []
for contour in contours:
# 计算轮廓的面积和周长
area = cv2.contourArea(contour)
perimeter = cv2.arcLength(contour, True)

# 根据面积和周长进行筛选
if area > 100 and perimeter > 50:
    filtered_contours.append(contour)

绘制筛选后的轮廓

contour_image = cv2.drawContours(image.copy(), filtered_contours, -1, (0, 255, 0), 2)

显示结果

cv2.imshow(‘Binary Image’, binary)
cv2.imshow(‘Filtered Contour Image’, contour_image)
cv2.waitKey(0)
cv2.destroyAllWindows()


在上述代码中,我使用了两个轮廓特征进行筛选:面积(area)和周长(perimeter)。根据实际需求,我设置了面积大于100且周长大于50的条件,您可以根据具体情况进行调整。


通过使用轮廓特征进行筛选,可以排除一些不需要的轮廓,只保留符合要求的文字轮廓。


请注意,轮廓特征的筛选条件需要根据具体需求进行调整。您可以根据文字的大小、形状等特征,结合实际情况来设定适合的筛选条件。


### 六、边缘检测算法示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/532888eb04a5452da12daab6a30c8139.png)下面是一个示例代码,演示了如何应用边缘检测算法(Canny边缘检测)来提取文字的边缘信息:



import cv2

读取图像

image = cv2.imread(‘your_image.jpg’, 0)

边缘检测

edges = cv2.Canny(image, 100, 200)

查找轮廓

contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

绘制轮廓

contour_image = cv2.drawContours(image.copy(), contours, -1, (0, 255, 0), 2)

显示结果

cv2.imshow(‘Edges Image’, edges)
cv2.imshow(‘Contour Image’, contour_image)
cv2.waitKey(0)
cv2.destroyAllWindows()


在上述代码中,我使用了Canny边缘检测算法来获取图像中文字的边缘信息。通过调整边缘检测的阈值(100和200),可以控制边缘检测的灵敏度,以获得清晰的文字边缘。


然后,使用`cv2.findContours`函数查找边缘图像中的轮廓,并使用`cv2.drawContours`函数绘制轮廓。


除了边缘检测,还可以尝试其他的图像分割算法,如基于区域的分割算法(如基于水平和垂直投影的方法)来将图像分割为文字和背景区域。


请注意,不同的图像处理技术适用于不同的场景和需求,您可以根据实际情况选择适合的技术来提取文字轮廓。


### 七、使用图像分割算法将图像分割为文字和背景区域示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/e933af9b3b474700bc4ee69a870008f9.png)基于区域的分割算法可以根据文字和背景的特征将图像分割为不同的区域。下面是一个示例代码,演示了如何使用基于区域的分割算法来将图像分割为文字和背景区域:



import cv2
import numpy as np

读取图像

image = cv2.imread(‘your_image.jpg’)

转换为灰度图像

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

二值化处理

_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

形态学操作(去除噪点)

kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=2)

查找轮廓

contours, _ = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

创建空白图像作为文字区域

text_region = np.zeros_like(image)

根据轮廓绘制文字区域

for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
cv2.drawContours(text_region, [contour], -1, (255, 255, 255), cv2.FILLED)

提取文字区域

text_only = cv2.bitwise_and(image, text_region)

显示结果

cv2.imshow(‘Original Image’, image)
cv2.imshow(‘Text Region’, text_region)
cv2.imshow(‘Text Only’, text_only)
cv2.waitKey(0)
cv2.destroyAllWindows()


在上述代码中,首先将彩色图像转换为灰度图像,然后使用自适应阈值二值化(Otsu’s方法)将图像转换为二值图像。接下来,通过形态学开运算去除噪点,然后使用`cv2.findContours`函数查找二值图像中的轮廓。


根据轮廓绘制一个与原始图像大小相同的空白图像,并使用`cv2.drawContours`函数将文字区域绘制为白色。最后,使用位运算`cv2.bitwise_and`提取原始图像中的文字区域。


请注意,基于区域的分割算法的效果可能会受到图像质量、光照条件等因素的影响。根据具体情况,您可以调整二值化的阈值、形态学操作的参数等来获得最佳的分割结果。


### 八、调整参数优化文字轮廓示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/68d42478bbf44f0980b31ce406e1bfe1.png)下面是一个示例代码,演示了如何通过调整参数来优化文字轮廓的提取效果:



import cv2

读取图像

image = cv2.imread(‘your_image.jpg’, 0)

自适应阈值二值化(调整参数)

binary = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 5)

形态学操作(调整参数)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dilated = cv2.dilate(binary, kernel, iterations=2)
eroded = cv2.erode(dilated, kernel, iterations=1)

查找轮廓

contours, _ = cv2.findContours(eroded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

筛选轮廓

filtered_contours = []
for contour in contours:
# 计算轮廓的面积和周长
area = cv2.contourArea(contour)
perimeter = cv2.arcLength(contour, True)

# 根据面积和周长进行筛选(调整参数)
if area > 100 and perimeter > 50:
    filtered_contours.append(contour)

绘制筛选后的轮廓

contour_image = cv2.drawContours(image.copy(), filtered_contours, -1, (0, 255, 0), 2)

显示结果

cv2.imshow(‘Binary Image’, binary)
cv2.imshow(‘Dilated Image’, dilated)
cv2.imshow(‘Eroded Image’, eroded)
cv2.imshow(‘Contour Image’, contour_image)
cv2.waitKey(0)

在这里插入图片描述

感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的:

① 2000多本Python电子书(主流和经典的书籍应该都有了)

② Python标准库资料(最全中文版)

③ 项目源码(四五十个有趣且经典的练手项目及源码)

④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

⑤ Python学习路线图(告别不入流的学习)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 11
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值