目录
一、彩色图形填充
1、初始效果展示
# 转二值图
def ToBinary():
global gray, binary
# 1、灰度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow('imgray', gray)
# 2、二进制图像
ret, binary = cv.threshold(gray, 127, 255, 0)
cv.imshow('binary', binary)
可以发现有些图形明显颜色不达标,甚至根本就没有显示。我们需要把所有图片轮廓锐化。
2、试错过程:
1、试错1:锐化显示所有图片
在灰度化之前,先进行锐化:
# 1、锐化
kernel = np.array([
[4, 4, 4],
[4, -32, 4],
[4, 4, 4]
])
sharp = cv.filter2D(img, -1, kernel)
cv.imshow('sharp', sharp)
图像处理被锐化的同时,噪声也被锐化,不可取。
2、试错2:用礼帽提取出明亮部分
# 礼帽
tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, (3,3), iterations=10)
cv.imshow('tophat', tophat)
礼帽(顶帽)处理效果如下:
可以看出,还是没有达到预期的效果。
同时,发现顶帽和底帽(礼帽和黑帽)确实名副其实,在这里,一个提取顶,一个提取底。(^_^)看看黑帽(底帽)效果吧:
3、正确方式:直接对图片亮度增强(不用形态学处理)
直接增强图片的亮度:
# 1、亮度增强
bright = cv.convertScaleAbs(img, None, 1.5, 30)
cv.imshow('bright', bright)
很好,达到了想要的效果。
所以有的时候思维不要局限,有时候简单的方法反而能更好的达到目标。
总代码
# 二值图内部填充
import cv2 as cv
import numpy as np
# 转二值图
def ToBinary():
global gray, binary
# 1、亮度增强
bright = cv.convertScaleAbs(img, None, 1.5, 30)
cv.imshow('bright', bright)
# 2、灰度化
gray = cv.cvtColor(bright, cv.COLOR_BGR2GRAY)
cv.imshow('gray', gray)
# 3、二进制图像
ret, binary = cv.threshold(gray, 127, 255, 0)
cv.imshow('binary', binary)
if __name__ == '__main__':
img = cv.imread('Resource/test7.jpg')
cv.imshow('img', img)
ToBinary() #转二进制图像
cv.waitKey(0)
二、硬币填充
1、初始效果展示
硬币直接转二值图效果:
可以看出:
1、右边的圈圈还是有一些瑕疵;
2、左边残留部分黑色区域。
2、试错
1、如果对它进行亮度增强
可以看出来,亮度增强明显是行不通的。
2、对它进行亮度减小
虽然能够填补空缺,但是它也被背景的黑色侵蚀的差不多了。
3、分析原图
感觉这张图像缺的不是亮度,个人感觉是暗度不均匀,因为右边图像出了问题,它和其他图像最大的区别就是过亮了。我们需要对其暗化。除了亮度变化,还有形态学能控制亮度:礼帽/黑帽。
4、黑帽处理
为了得到较暗的区域,我们需要对它进行黑帽处理。这里用矩形卷积核效果最好。
但默认是椭圆形,所以需要修改一下:
# 设置卷积核:矩形(默认椭圆形)
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (31, 31))
(卷积核默认椭圆形)
# 2、黑帽
kernel = cv.getStructuringElement(cv.MORPH_RECT, (31, 31))
blackhat = cv.morphologyEx(gray, cv.MORPH_BLACKHAT, kernel, iterations=1)
cv.imshow('blackhat', blackhat)
(一开始不知道,就是设置的默认椭圆形,改来改去没效果)
对比一下效果:
1、椭圆形卷积核
blackhat = cv.morphologyEx(gray, cv.MORPH_BLACKHAT, (31,31), iterations=1)
2、矩形卷积核
# 设置卷积核:矩形(默认椭圆形)
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (31, 31))
blackhat = cv.morphologyEx(gray, cv.MORPH_BLACKHAT, kernel, iterations=1)
5、设置合适的阈值,得到二值图
# 3、得到二进制图像(要设置好合适的阈值)
ret, binary = cv.threshold(blackhat, 30, 255, 0)
cv.imshow('binary', binary)
别思维固化了,二值图的阈值不一定必须得是127,为了得到目标,可以设置为其它阈值。(比如这里设置为30最佳)
对比一下效果:
1、127阈值
可以看到,什么都没有
2、30阈值
总代码
# 二值图内部填充(图形和硬币)
import cv2 as cv
import numpy as np
# 转二值图(图形)
def Figure_ToBinary():
img = cv.imread('Resource/test7.jpg')
cv.imshow('img', img)
# 1、亮度增强
bright = cv.convertScaleAbs(img, None, 1.5, 30)
cv.imshow('bright', bright)
# 2、灰度化
gray = cv.cvtColor(bright, cv.COLOR_BGR2GRAY)
cv.imshow('gray', gray)
# 3、二进制图像
ret, binary = cv.threshold(gray, 127, 255, 0)
cv.imshow('binary', binary)
#转二值图像(硬币)
def Coin_ToBinary():
img = cv.imread('Resource/test9.jpg')
cv.imshow('img', img)
# 1、灰度化
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow('gray', gray)
# 2、黑帽
# 设置卷积核:矩形(默认椭圆形)
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (31, 31))
blackhat = cv.morphologyEx(gray, cv.MORPH_BLACKHAT, kernel, iterations=1)
cv.imshow('blackhat', blackhat)
# 3、得到二进制图像(要设置好合适的阈值)
ret, binary = cv.threshold(blackhat, 30, 255, 0)
cv.imshow('binary', binary)
if __name__ == '__main__':
Figure_ToBinary() #转二值图像(图形)
Coin_ToBinary() #转二值图像(硬币)
cv.waitKey(0)