一、图像显示
import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
img = cv2.imread('cat.jpg',0)
plt.imshow(img,'gray')
小 TIPS
解决plt.imshow显示cv2.imread读取的图片有色差发蓝
出现的问题:
img = cv2.imrad('lina.jpg')
plt.imshow(img)
原因:使用cv2.imread()读取图像时,默认彩色图像的三通道顺序为B、G、R,这与我们所熟知的RGB中的R通道和B通道正好互换位置了。而使用plt.imshow()函数却默认显示图像的通道顺序为R、G、B,导致图像出现色差发蓝。
解决方法:
img = cv2.imread('lina.jpg')
def plt_show_img(image):
b,g,r = cv2.split(image)
img_new = cv2.merge([r,g,b])
plt.xticks([]), plt.yticks([])
plt.imshow(img_new)
plt_show_img(img)
二、边界填充
top_size, bottom_size, left_size, right_size = (100, 100, 100, 100)
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType = cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType = cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType = cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType = cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType = cv2.BORDER_CONSTANT)
plt.subplot(231), plt.imshow(img, 'gray'), plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT101')
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
BORDER_REPLICATE:复制最边缘像素
BORDER_REFLECT:对感兴趣的图像中的像素在两边进行复制,例如:fedcba|abcdefgh|hgfedcb
BORDER_REFLECT_101:以最边缘像素为轴,例如:hgfedcb|abcdefgh|gfedcba
BORDER_WRAP:外包装法,例如:bcdefgh|abcdefgh|abcdefg
BORDER_CONSTANT:常量法,常数值填充
三、平滑处理
1.均值滤波
相当于用nxn的一个卷积核对图像进行平均卷积操作,使一个位置的像素点与邻近像素点的值的差减小,从而减少邻近像素点之间的颜色差,进而达到平滑的效果。
#均值滤波:简单的平均卷积操作
blur_3 = cv2.blur(img, (3, 3))
blur_5 = cv2.blur(img, (5, 5))
blur_10 = cv2.blur(img, (9, 9))
blur_50 = cv2.blur(img, (51, 51))
plt.subplot(231), plt_show_img(img), plt.title('GRIGINAL')
plt.subplot(232), plt_show_img(blur_3), plt.title('blur_3')
plt.subplot(233), plt_show_img(blur_5), plt.title('blur_5')
plt.subplot(234), plt_show_img(blur_10), plt.title('blur_9')
plt.subplot(235), plt_show_img(blur_50), plt.title('blur_51')
2.方框滤波
基本和均值滤波差不多,多了一个Normalize参数,若选True,则和均值滤波相同;若选False,容易出现越界。
#方框滤波:基本和均值一样,但可以选择归一化
box_Nor_T = cv2.boxFilter(img, -1, (3, 3), normalize=True)
#-1表示输出结果和输入在通道上保持一致
box_Nor_F = cv2.boxFilter(img, -1, (3, 3), normalize=False)
plt.subplot(231), plt_show_img(img), plt.title('GRIGINAL')
plt.subplot(232), plt_show_img(box_Nor_T), plt.title('box_Nor_T')
plt.subplot(233), plt_show_img(box_Nor_F), plt.title('box_Nor_F')
3.高斯滤波
离中心点越近,所占权重越高
#高斯滤波:高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
gaussian_5 = cv2.GaussianBlur(img, (5, 5), 1)
plt.subplot(231), plt_show_img(img), plt.title('GRIGINAL')
plt.subplot(232), plt_show_img(gaussian_5), plt.title('GAUSSIAN_5')
4.中值滤波
用规定范围内数值的中间值来替代当前位置的数值
对于噪音点来说,用中值滤波效果最明显
#中值滤波:相当于用中值代替
median = cv2.medianBlur(img, 5)
median_21 = cv2.medianBlur(img, 21)
plt.subplot(231), plt_show_img(img), plt.title('GRIGINAL')
plt.subplot(232), plt_show_img(median), plt.title('MEDIAN')
plt.subplot(233), plt_show_img(median_21), plt.title('MEDIAN_21')
5展示所有
#展示所有
res = np.hstack((blur_3, gaussian_5, median))
plt_show_img(res)
四、腐蚀操作
效果展示:
import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
img = cv2.imread('dige.png')
def plt_show_img(img):
b, g, r = cv2.split(img)
img_new = cv2.merge([r, g, b])
plt.xticks([]),plt.yticks([])
plt.imshow(img_new)
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(img, kernel, iterations = 1)
plt.subplot(231), plt_show_img(img), plt.title('ORIGINAL')
plt.subplot(232), plt_show_img(erosion), plt.title('EROSION')
原理:用kernel大小的卷积核对图像进行复试,kernel越大能腐蚀的范围也就越大,iterations是迭代次数,迭代次数越多,腐蚀的程度越深。
1.修改迭代次数的效果:
erosion_1 = cv2.erode(img, kernel, iterations = 1)
erosion_2 = cv2.erode(img, kernel, iterations = 2)
erosion_3 = cv2.erode(img, kernel, iterations = 3)
plt.subplot(231), plt_show_img(img), plt.title('ORIGINAL')
plt.subplot(232), plt_show_img(erosion_1), plt.title('EROSION_1')
plt.subplot(233), plt_show_img(erosion_2), plt.title('EROSION_2')
plt.subplot(234), plt_show_img(erosion_3), plt.title('EROSION_3')
2.修改卷积核大小的效果:
kernel_3 = np.ones((3, 3), np.uint8)
kernel_30 = np.ones((30, 30), np.uint8)
kernel_150 = np.ones((150, 150), np.uint8)
erosion_3 = cv2.erode(img_c, kernel_3, iterations = 1)
erosion_30 = cv2.erode(img_c, kernel_30, iterations = 1)
erosion_150 = cv2.erode(img_c, kernel_150, iterations = 1)
plt.subplot(231), plt_show_img(img_c), plt.title('ORIGINAL')
plt.subplot(232), plt_show_img(erosion_3), plt.title('EROSION_3')
plt.subplot(233), plt_show_img(erosion_30), plt.title('EROSION_30')
plt.subplot(234), plt_show_img(erosion_150), plt.title('EROSION_150')
五、膨胀操作
相当于腐蚀的逆操作
kernel = np.ones((3, 3), np.uint8)
img_erosion = cv2.erode(img, kernel, iterations = 1)
img_dilate = cv2.dilate(img_erosion, kernel, iterations = 1)
plt.subplot(232), plt_show_img(img), plt.title('ORIGINAL')
plt.subplot(233), plt_show_img(img_erosion), plt.title('EROSION')
plt.subplot(234), plt_show_img(img_dilate), plt.title('DILATE')
改变卷积核大小的效果:
kernel_3 = np.ones((3, 3), np.uint8)
kernel_7 = np.ones((7, 7), np.uint8)
kernel_11 = np.ones((11, 11), np.uint8)
img_dilate_3 = cv2.dilate(img_erosion, kernel_3, iterations = 1)
img_dilate_7 = cv2.dilate(img_erosion, kernel_7, iterations = 1)
img_dilate_11 = cv2.dilate(img_erosion, kernel_11, iterations = 1)
plt.subplot(231), plt_show_img(img_dilate_3), plt.title('DILATE_3')
plt.subplot(232), plt_show_img(img_dilate_7), plt.title('DILATE_7')
plt.subplot(233), plt_show_img(img_dilate_11), plt.title('DILATE_11')
改变迭代次数的效果:
img_dilate_1 = cv2.dilate(img_erosion, kernel, iterations = 1)
img_dilate_3 = cv2.dilate(img_erosion, kernel, iterations = 3)
img_dilate_5 = cv2.dilate(img_erosion, kernel, iterations = 5)
plt.subplot(231), plt_show_img(img_dilate_1), plt.title('DILATE_1')
plt.subplot(232), plt_show_img(img_dilate_3), plt.title('DILATE_3')
plt.subplot(233), plt_show_img(img_dilate_5), plt.title('DILATE_5')
六、开运算和闭运算
开运算:先腐蚀,再膨胀。可以去毛刺、噪声,并保留主要部分。
闭运算:先膨胀,再腐蚀。有助于关闭前景物体内部的小孔,或物体上的小黑点。
#开运算
kernel = np.ones((5, 5), np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
plt.subplot(231),plt_show_img(img)
plt.subplot(232),plt_show_img(opening)
#闭运算
kernel = np.ones((5, 5), np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
plt.subplot(231), plt_show_img(img)
plt.subplot(232), plt_show_img(closing)
放大看还是有变化的
七、梯度运算
膨胀运算 - 腐蚀运算,即膨胀图像减去腐蚀图像,可以得到图像轮廓。
circle = cv2.imread('circle.png')
kernel = np.ones((21, 21), np.uint8)
dilate = cv2.dilate(circle, kernel, iterations = 1)
erosion = cv2.erode(circle, kernel, iterations =1)
gradient = cv2.morphologyEx(circle, cv2.MORPH_GRADIENT, kernel)
plt.subplot(231), plt_show_img(circle), plt.title('ORIGINAL')
plt.subplot(232), plt_show_img(dilate), plt.title('DILATE')
plt.subplot(233), plt_show_img(erosion), plt.title('EROSION')
plt.subplot(234), plt_show_img(gradient), plt.title('GRADIENT')
八、礼帽和黑帽
礼帽:原始输入 - 开运算结果,只留下毛刺、噪点,用来分离比邻近点亮一些的斑块。
黑帽:闭运算 - 原始输入,用来分离比邻近点暗一些的斑块。
#卷积核大小为5X5的礼帽和黑帽
kernel = np.ones((5,5), np.uint8)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
#卷积核大小为9X9的礼帽和黑帽
kernel_1 = np.ones((9,9), np.uint8)
tophat_1 = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel_1)
blackhat_1 = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel_1)
plt.subplot(231), plt_show_img(img), plt.title('ORGINAL')
plt.subplot(232), plt_show_img(tophat), plt.title('TOPHAT')
plt.subplot(233), plt_show_img(blackhat), plt.title('BLACKHAT')
plt.subplot(235), plt_show_img(tophat_1), plt.title('TOPHAT')
plt.subplot(236), plt_show_img(blackhat_1), plt.title('BLACKHAT')