OpenCV圖像處理:閾值分割、邊緣檢測、數學形態學、濾波


1. OpenCV簡介
在這里插入圖片描述

OpenCV是一個基於BSD許可(開源)發行的跨平台計算機視覺和機器學習軟件庫,可以運行在Linux、Windows、Android和Mac OS操作系統上(未來期待在Harmony OS上運行).
它輕量級而且高效——由一系列 C 函數和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口,實現了圖像處理和計算機視覺方面的很多通用算法。

2. Opencv模塊

模塊 功能
Core 核心模塊,包含最基礎的操作
Imgproc 圖像處理模塊
Objdectect 目標檢測模塊
Feature2D 2D特征檢測模塊
Video 視頻處理模塊
HighGUI 高層圖像用戶界面
Calib3d 3D重建模塊
ML 機器學習模塊
FLANN 最近鄰搜索模塊
Stitching 圖像拼接模塊
Photo 計算圖像學
Superres 超分辨率模塊
GPU GPU並行加速模塊

3. OpenCV總覽

在這里插入圖片描述

OpenCV框架中的每一個模塊都包含大量的計算機視覺方法,每一個模塊都能獨當一面,功能強大。

本篇文章將介紹OpenCV庫中最重要的模塊:Imgproc(圖像處理模塊)。

在這里插入圖片描述

圖像處理模塊包括:圖像的讀取、顯示、保存;幾何運算;灰度變換幾何變換平滑、銳化數學形態學閾值分割邊緣檢測色彩空間;形狀繪制等。

@

  • 圖像讀取、顯示、保存

函數 功能
cv2.imread( ) 圖像讀取
cv2.imshow( ) 圖像顯示
cv2.imwrite( ) 圖像保存
"""圖像讀取、顯示、保存"""

img = cv2.imread('shiyuan.png')
cv2.imwrite('shi.png',img)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在這里插入圖片描述


  • 幾何運算

函數 功能
img1+img2 圖像加法
cv2.addWeight( ) 圖像融合
"""幾何運算"""

img1 = cv2.imread('shiyuan.png')
img2 = cv2.imread('lizi.png')

img3 = cv2.resize(img1,(300,300))+cv2.resize(img2,(300,300))
img4 = cv2.addWeighted(cv2.resize(img1,(300,300)),0.3,cv2.resize(img2,(300,300)),0.7,20)

cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.waitKey(0)
cv2.destroyAllWindows()

在這里插入圖片描述

在這里插入圖片描述


  • 灰度變換

函數 功能
對數變換 變換圖像灰度
伽馬變換 變換圖像灰度
直方圖均衡化 變換圖像灰度
直方圖規定化 變換圖像灰度
"""灰度變換"""

import cv2
import copy

img = cv2.imread('bai.png',1)
img1 = cv2.imread('bai.png',0)
img = cv2.resize(img,(400,300))
img1 = cv2.resize(img,(400,300))
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#伽馬變換
gamma = copy.deepcopy(gray)
rows = img.shape[0]
cols = img.shape[1]
for i in range(rows):
    for j in range(cols):
        gamma[i][j]=3*pow(gamma[i][j],0.8)

cv2.imshow('img',img)
cv2.imshow('gray',img1)
cv2.imshow('gamma',gamma)

cv2.waitKey(0)
cv2.destroyAllWindows()
"""灰度變換"""

import cv2
import copy
import math

img = cv2.imread('bai.png',1)
img1 = cv2.imread('bai.png',0)
img = cv2.resize(img,(400,300))
img1 = cv2.resize(img,(400,300))
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#對數變換
logc = copy.deepcopy(gray)
rows=img.shape[0]
cols=img.shape[1]
for i in range(rows):
    for j in range(cols):
        logc[i][j] = 3 * math.log(1 + logc[i][j])
        
cv2.imshow('img',img)
cv2.imshow('gray',img1)
cv2.imshow('logc',logc)

cv2.waitKey(0)
cv2.destroyAllWindows()

在這里插入圖片描述

"""灰度變換"""

import cv2
import copy
import math

img = cv2.imread('bai.png',1)
img1 = cv2.imread('bai.png',0)
img = cv2.resize(img,(400,300))
img1 = cv2.resize(img,(400,300))
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 反色變換
cover=copy.deepcopy(gray)
rows=img.shape[0]
cols=img.shape[1]
for i in range(rows):
    for j in range(cols):
        cover[i][j]=255-cover[i][j]

#通過窗口展示圖片 第一個參數為窗口名 第二個為讀取的圖片變量
cv2.imshow('img',img)
cv2.imshow('gray',img1)
cv2.imshow('cover',cover)
cv2.waitKey(0)
cv2.destroyAllWindows()

在這里插入圖片描述

#直方圖規定化

import cv2

import numpy as np

import matplotlib.pyplot as plt

img0=cv2.imread('hua.png')#讀取原圖片

scr=cv2.imread('tu.png')#讀取目標圖片

#把兩張圖片轉成真正的灰度圖片,因為自己只會做灰度圖片的規定化

img0=cv2.cvtColor(img0,cv2.COLOR_BGR2GRAY)

img=img0.copy()#用於之后做對比圖

scr=cv2.cvtColor(scr,cv2.COLOR_BGR2GRAY)

mHist1=[]

mNum1=[]

inhist1=[]

mHist2=[]

mNum2=[]

inhist2=[]

#對原圖像進行均衡化
for i in range(256):

    mHist1.append(0)

row,col=img.shape#獲取原圖像像素點的寬度和高度



for i in range(row):

    for j in range(col):

        mHist1[img[i,j]]= mHist1[img[i,j]]+1#統計灰度值的個數

mNum1.append(mHist1[0]/img.size)

for i in range(0,255):

    mNum1.append(mNum1[i]+mHist1[i+1]/img.size)

for i in range(256):

    inhist1.append(round(255*mNum1[i]))
    
 #對目標圖像進行均衡化

for i in range(256):

    mHist2.append(0)

rows,cols=scr.shape#獲取目標圖像像素點的寬度和高度

for i in range(rows):

    for j in range(cols):

        mHist2[scr[i,j]]= mHist2[scr[i,j]]+1#統計灰度值的個數

mNum2.append(mHist2[0]/scr.size)

for i in range(0,255):

    mNum2.append(mNum2[i]+mHist2[i+1]/scr.size)

for i in range(256):

    inhist2.append(round(255*mNum2[i]))

在這里插入圖片描述


  • 幾何變換

函數 功能
cv2.resize( ) 圖像縮放
cv2.warpAffine( ) 圖像平移
cv2.getRotationMatrix2D( ) cv2.warpAffine( ) 圖像旋轉
cv2.getAffineTransform( ) cv2.warpAffine( ) 仿射變換
cv2.getPerspectiveTransform( ) cv2.warpPerspective( ) 透射變換
cv2.pyrUp( ) 高斯金字塔上采樣
cv2.pyrDown( ) 高斯金字塔下采樣
img-cv2.pyrUp(cv2.pyrDown(img)) 拉普拉斯金字塔
"""幾何變換"""

img = cv2.imread('shiyuan.png')

img1 = cv2.resize(img,(300,300))

M = np.float32([[1,0,30],[0,1,60]])
img2 = cv2.warpAffine(img1,M,(300,300))
img2 = cv2.putText(img2,'panning',(20,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)

M = cv2.getRotationMatrix2D(((300-1)/2.0,(300-1)/2.0),45,1)
img3 = cv2.warpAffine(img1,M,(300,300))
img3 = cv2.putText(img3,'rotation',(20,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)

matr1 = np.float32([[50,50],[200,50],[50,200]])
matr2 = np.float32([[10,100],[200,50],[100,250]])
M = cv2.getAffineTransform(matr1,matr2)
img4 = cv2.warpAffine(img1,M,(300,300))
img4 = cv2.putText(img4,'affine',(20,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)

matr1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
matr2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(matr1,matr2)
img5 = cv2.warpPerspective(img1,M,(300,300))
img5 = cv2.putText(img5,'perspective',(20,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)

cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.imshow('img5',img5)
cv2.waitKey(0)
cv2.destroyAllWindows()

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

"""圖像金字塔"""

import cv2 

#高斯金字塔
def pyramid_demo(image):
    level = 2     
    temp = image.copy()  
    pyramid_images = []  
    for i in range(level):
        dst = cv2.pyrDown(temp)   
        pyramid_images.append(dst)  
        cv2.imshow("pyramid"+str(i+1), dst)
        temp = dst.copy()
    return pyramid_images

#拉普拉斯金字塔
def lapalian_demo(image):
    pyramid_images = pyramid_demo(image)    
    level = len(pyramid_images)
    for i in range(level-1, -1, -1):
        if (i-1) < 0:
            expand = cv2.pyrUp(pyramid_images[i], dstsize = image.shape[:2])
            lpls = cv2.subtract(image, expand)
            cv2.imshow("lapalian_down_"+str(i+1), lpls)
        else:
            expand = cv2.pyrUp(pyramid_images[i], dstsize = pyramid_images[i-1].shape[:2])
            lpls = cv2.subtract(pyramid_images[i-1], expand)
            cv2.imshow("lapalian_down_"+str(i+1), lpls)
            
src = cv2.resize(cv2.imread('shiyuan.png'),(256,256))
cv2.namedWindow('input_image') 
cv2.imshow('input_image', src)
lapalian_demo(src)
cv2.waitKey(0)
cv2.destroyAllWindows()

在這里插入圖片描述

"""直方圖均衡化"""

import cv2
import numpy as np
img = cv2.imread('bai.png',0)
img = cv2.resize(img,(400,300))
equ = cv2.equalizeHist(img)
cv2.imshow('img',equ)
cv2.waitKey()
cv2.destroyAllWindows()

  • 平滑、銳化

函數 功能
cv2.blur( ) 均值濾波
cv2.GaussianBlur( ) 高斯濾波
cv2.medianBlur( ) 中值濾波
cv2.bilateralFilter( ) 雙邊濾波
"""平滑、銳化"""
import cv2

img = cv2.imread('shiyuan.png')
img = cv2.resize(img,(300,300))
img1 = cv2.blur(img,(11,11))
img2 = cv2.GaussianBlur(img,(11,11),0)
img3 = cv2.medianBlur(img,11)
img4 = cv2.bilateralFilter(img,9,75,75)

M = np.ones((5, 5), np.float32) / 25
img5 = cv.filter2D(img, -1, M)

cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.imshow('img5',img5)

cv2.waitKey(0)
cv2.destroyAllWindows()

  • 數學形態學

函數 功能
cv2.erode( ) 腐蝕
cv2.dilate( ) 膨脹
cv2.morphologyEx(,cv2.MORPH_OPEN) 開運算
cv2.morphologyEx(,cv2.MORPH_CLOSE) 閉運算
cv2.morphologyEx(,cv2.MORPH_TOPHAT) 頂帽運算
cv2.morphologyEx(,cv2.MORPH_BLACKHAT) 底帽運算
cv2.morphologyEx(,cv2.MORPH_GRADIENT) 形態學梯度
"數學形態學"

import cv2

img = cv2.imread('shiyuan.png')
img = cv2.resize(img,(300,300))

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))

img1 = cv2.dilate(img, kernel)
img2 = cv2.erode(img,kernel)

#設置結構元
kernel_rect=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
kernel_cross=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
kernel_ellipse=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))

#圖像開運算處理
open_rect=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel_rect)
open_cross=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel_cross)
open_ellipse=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel_ellipse)

#圖像閉運算處理
close_rect=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel_rect)
close_cross=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel_cross)
close_ellipse=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel_ellipse)

gradient_rect = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel_rect)
gradient_cross = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel_cross)
gradient_ellipse = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel_ellipse)

#頂帽變換
tophat_rect=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel_rect)
tophat_cross=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel_cross)
tophat_ellipse=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel_ellipse)

#頂帽變換
blackhat_rect=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel_rect)
blackhat_cross=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel_cross)
blackhat_ellipse=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel_ellipse)

cv2.imshow('blackhat_rect',blackhat_rect)
cv2.imshow('blackhat_cross',blackhat_cross)
cv2.imshow('blackhat_ellipse',blackhat_ellipse)
cv2.imshow('tophat_rect',tophat_rect)
cv2.imshow('tophat_cross',tophat_cross)
cv2.imshow('tophat_ellipse',tophat_ellipse)
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('open_rect',open_rect)
cv2.imshow('open_cross',open_cross)
cv2.imshow('open_ellipse',open_ellipse)
cv2.imshow('close_rect',close_rect)
cv2.imshow('close_cross',close_cross)
cv2.imshow('close_ellipse',close_ellipse)
cv2.imshow('gradient_rect',gradient_rect)
cv2.imshow('gradient_cross',gradient_cross)
cv2.imshow('gradient_ellipse',gradient_ellipse)
cv2.waitKey(0)
cv2.destroyAllWindows()

在這里插入圖片描述


  • 閾值分割

函數 功能
cv2.threshold(,cv2.THRESH_BINARY) 二值化閾值
cv2.threshold(,cv2.THRESH_BINARY_INV) 反二值化閾值
cv2.threshold(,cv2.THRESH_TOZERO) 低閾值零處理
cv2.threshold(,cv2.THRESH_TOZERO_INV) 超閾值零處理
cv2.threshold(,cv2.THRESH_OSTU) 大津算法
cv2.threshold(,cv2.THRESH_TRIANGLE) 截斷閾值化處理
cv2.adaptiveThreshold(,,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,) 自適應閾值處理
cv2.adaptiveThreshold(,,cv2.ADAPTIVE_THRESH_MEAN_C,) 自適應閾值處理
"閾值分割"

import cv2

img = cv2.imread('shiyuan.png')
img = cv2.resize(img,(400,300))
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,img1 = cv2.threshold(img,110,255,cv2.THRESH_BINARY)
ret,img2 = cv2.threshold(img,110,255,cv2.THRESH_BINARY_INV)
ret,img3 = cv2.threshold(img,110,255,cv2.THRESH_TOZERO)
ret,img4 = cv2.threshold(img,110,255,cv2.THRESH_TOZERO_INV)
ret,img5 = cv2.threshold(img,110,255,cv2.THRESH_TRUNC)
ret,img6 = cv2.threshold(img,110,255,cv2.THRESH_TRIANGLE)
ret,img7 = cv2.threshold(img,110,255,cv2.THRESH_OTSU)
ret,img8 = cv2.threshold(cv2.GaussianBlur(img,(7,7),0),110,255,cv2.THRESH_OTSU)
img9 = cv2.adaptiveThreshold(img,127, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 9, 11)
img10 = cv2.adaptiveThreshold(img,127,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,9,11)

cv2.imshow('img',img)
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.imshow('img5',img5)
cv2.imshow('img6',img6)
cv2.imshow('img7',img7)
cv2.imshow('img8',img8)
cv2.imshow('img9',img9)
cv2.imshow('img10',img10)
cv2.waitKey(0)
cv2.destroyAllWindows()

  • 邊緣檢測

函數 功能
cv2.Canny( ) Canny算子
cv2.findContours( ) 輪廓檢測
cv2.filter2D( ) 邊緣提取
"邊緣檢測"

import cv2

img = cv2.imread('bai.png')
img = cv2.resize(img,(400,300))
img1 = cv2.Canny(img,123,5)
 
cv2.imshow('img1',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""邊緣檢測"""

import cv2  
  
img = cv2.imread('bai.png')  
img = cv2.resize(img,(400,300))
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  
  
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)  
cv2.drawContours(img,contours,-1,(0,0,255),1)  
  
cv2.imshow("img", img)  
cv2.waitKey(0)  
cv2.destroyAllWindows()
"""邊緣檢測"""

import cv2
import numpy as np
def find_contours(kernel):
    img = cv2.imread('bai.png')
    img = cv2.resize(img,(400,300))
    img1 = cv2.filter2D(img,-1,kernel)
    cv2.imshow('img1',img1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

kernel1 = np.array((
        [0.0625, 0.125, 0.0625],
        [0.125, 0.25, 0.125],
        [0.0625, 0.125, 0.0625]), dtype="float32")

#Sobel算子
kernel2 = np.array(([-1,-2,-1],
                   [0,0,0],
                   [1,2,1]))

kernel3 = np.array(([-2,-1,0],
                   [-1,1,1],
                   [0,-1,-2]))

kernel4 = np.array([[-1,-1,-1],
                  [-1,8,-1],
                  [-1,-1,-1]])

kernel5 = np.array([[0,-1,0],
                   [-1,5,-1],
                   [0,-1,0]])

kernel6 = np.array([[0,1,0],
                   [1,-4,1],
                   [0,1,0]])

find_contours(kernel1)
find_contours(kernel2)
find_contours(kernel3)
find_contours(kernel4)
find_contours(kernel5)
find_contours(kernel6)

在這里插入圖片描述


  • 色彩空間

函數 功能
cv2.cvtColor(,cv2.COLOR_BGR2GRAY) 圖像灰度化
cv2.cvtColor(,cv2.COLOR_BGR2HSV) RGB轉HSV
"""色彩空間"""

import cv2

img = cv2.imread('bai.png')
img = cv2.resize(img,(400,300))
img1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

在這里插入圖片描述


  • 形狀繪制

函數 功能
cv2.line( ) 繪制直線
cv2.circle( ) 繪制圓圈
cv2.ellipse( ) 繪制橢圓
cv2.rectangle( ) 繪制矩形
cv2.arrowedLine( ) 繪制箭頭
cv2.putText( ) 繪制文本
"""形狀繪制"""

import cv2

img = cv2.imread('bai.png')
img = cv2.resize(img,(400,300))
imgx = img.copy()
imgy = img.copy()
imgz = img.copy()
imgw = img.copy()

img = cv2.resize(img,(400,300))
img1 = cv2.line(img,(10,10),(200,300),(0,0,255),2)
img2 = cv2.circle(imgx,(60,60),30,(0,0,213),-1)
img3 = cv2.rectangle(imgy,(10,10),(100,80),(0,0,200),2)
img4 = cv2.ellipse(imgz,(256,256),(50,40),0,5,360,(20,213,79),-1)

font=cv2.FONT_HERSHEY_SIMPLEX
img5 = cv2.putText(imgw,'opencv',(80,90), font, 2,(255,255,255),3)

cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.imshow('img5',img5)
cv2.waitKey(0)
cv2.destroyAllWindows()

在這里插入圖片描述
在這里插入圖片描述


寫在最后

在這里插入T圖片描述
資料包
下一期將扒拉sklearn庫,該庫是做機器學習的不二之選,歡迎大家搬好小板凳呀!


免責聲明!

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



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