openCV 一 安裝、圖像二值化、邊緣檢測


安裝

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()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM