安裝
1、window + pycharm
圖像二值化(轉自:假小牙)
threshold:固定閾值二值化
ret, dst = cv2.threshold(src, thresh, maxval, type)
- src: 輸入圖,只能輸入單通道圖像,通常來說為灰度圖
- dst: 輸出圖
- thresh: 閾值
- maxval: 當像素值超過了閾值(或者小於閾值,根據type來決定),所賦予的值
- type:二值化操作的類型,包含以下5種類型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
官方文檔的示例代碼:
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('gradient.png',0) ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC) ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO) ret,thresh5 = cv2.threshold(img,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()
adaptiveThreshold:自適應閾值二值化
自適應閾值二值化函數根據圖片一小塊區域的值來計算對應區域的閾值,從而得到也許更為合適的圖片。
dst = cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C)
- src: 輸入圖,只能輸入單通道圖像,通常來說為灰度圖
- dst: 輸出圖
- maxval: 當像素值超過了閾值(或者小於閾值,根據type來決定),所賦予的值
- thresh_type: 閾值的計算方法,包含以下2種類型:cv2.ADAPTIVE_THRESH_MEAN_C; cv2.ADAPTIVE_THRESH_GAUSSIAN_C.
- type:二值化操作的類型,與固定閾值函數相同,包含以下5種類型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV.
- Block Size: 圖片中分塊的大小
- C :閾值計算方法中的常數項
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('sudoku.png', 0) img = cv2.medianBlur(img, 5) ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) th2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) titles = ['Original Image', 'Global Thresholding (v = 127)', 'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding'] images = [img, th1, th2, th3] for i in range(4): plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]), plt.yticks([]) plt.show()
Otsu’s Binarization: 基於直方圖的二值化 (Otsu:最大類間方差法)
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('noisy2.png', 0) # global thresholding ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # Otsu's thresholding ret2, th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # Otsu's thresholding after Gaussian filtering blur = cv2.GaussianBlur(img, (5, 5), 0) ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # plot all the images and their histograms images = [img, 0, th1, img, 0, th2, blur, 0, th3] titles = ['Original Noisy Image', 'Histogram', 'Global Thresholding (v=127)', 'Original Noisy Image', 'Histogram', "Otsu's Thresholding", 'Gaussian filtered Image', 'Histogram', "Otsu's Thresholding"] for i in range(3): plt.subplot(3, 3, i * 3 + 1), plt.imshow(images[i * 3], 'gray') plt.title(titles[i * 3]), plt.xticks([]), plt.yticks([]) plt.subplot(3, 3, i * 3 + 2), plt.hist(images[i * 3].ravel(), 256) plt.title(titles[i * 3 + 1]), plt.xticks([]), plt.yticks([]) plt.subplot(3, 3, i * 3 + 3), plt.imshow(images[i * 3 + 2], 'gray') plt.title(titles[i * 3 + 2]), plt.xticks([]), plt.yticks([]) plt.show()
邊緣檢測
1、邊緣檢測濾波函數(Laplacian,Sobel,Scharr),濾波函數會把非邊緣區域轉換為黑色,將邊緣區域轉化白色或其他飽和的顏色。
2、由於濾波函數會把噪聲識別為邊緣,緩解這個問題的辦法是對圖像進行模糊處理
3、得到Laplacian函數的結果后,需要將其轉化為黑色邊緣和白色背景的圖像,然后將其歸一化(使其像素值在0和1之間,並乘以原圖以便能將邊緣變黑)
import numpy as np import cv2 def strokeEdge(src, dst, blurKsize=7, edgeKsize=5): if blurKsize >= 3: blurSrc = cv2.medianBlur(src, blurKsize) graySrc = cv2.cvtColor(blurSrc, cv2.COLOR_BGR2GRAY) else: graySrc = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) cv2.Laplacian(graySrc, cv2.CV_8U, graySrc, ksize=edgeKsize) normalizedInverseAlpha = (1.0 / 255) * (255 - graySrc) channels = cv2.split(src) for channel in channels: channel[:] = channel * normalizedInverseAlpha cv2.merge(channels, dst) cv2.imshow("origin", src) cv2.imshow("Laplacian", graySrc) cv2.imshow("normalizedInverse", dst) if __name__ == '__main__': img = cv2.imread("img/1.jpg") image = np.zeros(img.shape,img.dtype) strokeEdge(img, image) cv2.waitKey(0)
Canny邊緣檢測
img = cv2.imread("img/1.jpg", 0) # cv2.imwrite("canny.jpg",cv2.Canny(img, 200, 300)) cv2.imshow("origin", img) cv2.imshow("canny", cv2.Canny(img, 200, 300)) cv2.waitKeyEx(0) cv2.destroyAllWindows()