OpenCV图像处理
1. 图像阈值
ret, dst = cv2.threshold(src, thresh, maxval, type)
src : 输入图,只能输入单通道图像,通常来说为灰度图dst : 输出图thresh : 阈值maxval : 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值type :二值化操作的类型,包含以下5种类型:
- cv2.THRESH_BINARY : 超过阈值部分取maxval(最大值),否则取0
- cv2.THRESH_BINARY_INV : THRESH_BINARY的反转
- cv2.THRESH_TRUNC :大于阈值部分设为阈值,否则不变
- cv2.THRESH_TOZERO :大于阈值部分不改变,否则设为0
- cv2.THRESH_TOZERO_INV :THRESH_TOZERO的反转
import cv2
import matplotlib.pyplot as plt
img=cv2.imread('../image/cat.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
2. 图像平滑
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('../image/lenaNoise.png')[:,:,::-1]
blur = cv2.blur(img, (3, 3))
box1 = cv2.boxFilter(img,-1,(3,3), normalize=True)
box2 = cv2.boxFilter(img,-1,(3,3), normalize=False)
aussian = cv2.GaussianBlur(img, (5, 5), 1)
median = cv2.medianBlur(img, 5)
plt.subplot(231),plt.imshow(img,"gray"),plt.title("img")
plt.subplot(232),plt.imshow(box1),plt.title("box1")
plt.subplot(233),plt.imshow(box2),plt.title("box2")
plt.subplot(234),plt.imshow(blur),plt.title("blur")
plt.subplot(235),plt.imshow(aussian),plt.title("aussian")
plt.subplot(236),plt.imshow(median),plt.title("median")
plt.show()
3. 形态学操作
3.1 腐蚀
腐蚀与膨胀十分相似,同样也是将原图以及任意形状的内核进行卷积。不同的是进行膨胀操作时,将内核划过图像,提取内核覆盖的最小像素值,代替锚点位置的像素。这个操作会使图像中的“暗区”扩展。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('../image/wz.png')
kernel = np.ones((3,3),np.uint8)
img_erode = cv2.erode(img,kernel,iterations = 2)
plt.subplot(121),plt.imshow(img,"gray"),plt.title("img")
plt.subplot(122),plt.imshow(img_erode,"gray"),plt.title("img_erode")
plt.show()
3.2 膨胀
膨胀操作是将原图以及任意形状的内核进行卷积,内核中有一个可定义的锚点,称为内核中心点。进行膨胀操作时,将内核划过图像,提取内核覆盖的最大像素值,代替锚点位置的像素。这个操作会使图像中的“亮区”扩展。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('../image/wz.png')
kernel = np.ones((3,3),np.uint8)
img_dilate = cv2.dilate(img,kernel,iterations = 2)
plt.subplot(121),plt.imshow(img,"gray"),plt.title("img")
plt.subplot(122),plt.imshow(img_dilate,"gray"),plt.title("img_dilate")
plt.show()
3.3 开运算与闭运算
开运算与闭运算的异同
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('../image/wz.png')
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
plt.subplot(131),plt.imshow(img,"gray"),plt.title("img")
plt.subplot(132),plt.imshow(opening,"gray"),plt.title("opening")
plt.subplot(133),plt.imshow(closing,"gray"),plt.title("closing")
plt.show()
3.4 梯度运算
梯度=膨胀-腐蚀
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('../image/wz.png')
kernel = np.ones((5,5),np.uint8)
dilate = cv2.dilate(img,kernel,iterations = 2)
erosion = cv2.erode(img,kernel,iterations = 2)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
plt.subplot(221),plt.imshow(img,"gray"),plt.title("img")
plt.subplot(222),plt.imshow(dilate,"gray"),plt.title("dilate")
plt.subplot(223),plt.imshow(erosion,"gray"),plt.title("erosion")
plt.subplot(224),plt.imshow(gradient,"gray"),plt.title("gradient")
plt.show()
3.5 礼帽与黑帽
-
礼帽 = 原始输入-开运算结果 -
黑帽 = 闭运算-原始输入
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('../image/wz.png')
kernel = np.ones((5,5),np.uint8)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
plt.subplot(131),plt.imshow(img,"gray"),plt.title("img")
plt.subplot(132),plt.imshow(tophat,"gray"),plt.title("tophat")
plt.subplot(133),plt.imshow(gradient,"gray"),plt.title("gradient")
3.6 getStructuringElement()
图像处理经常要用到形态学操作,其中首先要获取结构元素。包括结构元素的大小及形状。cv2.getStructuringElement()返回一个特定大小与形状的结构元素用于形态学操作。
使用 Numpy 构建结构化元素是正方形的。但有时我们需要构建一个椭圆形/圆形的核。为了实现这种要求,提供了 OpenCV函数 cv2.getStructuringElement()。你只需要告诉他你需要的核的形状和大小。
cv.getStructuringElement( shape, ksize[, anchor] )
参数:
shape : 元素形状,OpenCV 中提供了三种,MORPH_RECT(矩阵) ,MORPH_CORSS(交叉形状) ,MORPH_ELLIPSE(椭圆) ;ksize ,结构元素的大小;anchor ,元素内的描点位置,默认为 (-1,-1) 表示形状中心;值得注意的时,只有 MORPH-CROSS 形状依赖 描点位置,其它情况 描点仅调节其他形态运算结果偏移了多少
import cv2
import numpy as np
kernel = np.ones((5,5),np.uint8)
kernel_1 = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
print("矩形:\n%s" %kernel)
kernel_2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
print("椭圆:\n%s" %kernel_2)
kernel_3 = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
print("十字:\n%s" %kernel_3)
矩形:
[[1 1 1 1 1]
[1 1 1 1 1]
[1 1 1 1 1]
[1 1 1 1 1]
[1 1 1 1 1]]
椭圆:
[[0 0 1 0 0]
[1 1 1 1 1]
[1 1 1 1 1]
[1 1 1 1 1]
[0 0 1 0 0]]
十字:
[[0 0 1 0 0]
[0 0 1 0 0]
[1 1 1 1 1]
[0 0 1 0 0]
[0 0 1 0 0]]
参考链接:https://www.cnblogs.com/zeroing0/p/14127411.html
3.7 morphologyEx()
cv.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]
参数:
src ,预处理的图像;op ,形态操作的类型,可选择一种类型
- 开运算 : cv2.MORPH_OPEN : 2
- 闭运算 : cv2.MORPH_CLOSE: 3
- 梯度运算 : cv2.MORPH_GRADIENT: 4
- 礼帽 : cv2.MORPH_TOPHAT: 5
- 黑帽 : cv2.MORPH_BLACKHAT: 6
kernel : 结构元素,来自于 getStructuringElement 方法
参考链接: https://www.cnblogs.com/zeroing0/p/14127411.html http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html
|