功能強(qiáng)大的python包(四):OpenCV

1. OpenCV簡介

image

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

2. Opencv模塊

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

3. OpenCV總覽

image

OpenCV框架中的每一個模塊都包含大量的計算機(jī)視覺方法,每一個模塊都能獨(dú)當(dāng)一面,功能強(qiáng)大。

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

image

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


  • 圖像讀取、顯示、保存

函數(shù) 功能
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()
image

  • 幾何運(yùn)算

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

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

  • 灰度變換

函數(shù) 功能
對數(shù)變換 變換圖像灰度
伽馬變換 變換圖像灰度
直方圖均衡化 變換圖像灰度
直方圖規(guī)定化 變換圖像灰度
"""灰度變換"""

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)

#對數(shù)變換
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()
image
"""灰度變換"""

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]

#通過窗口展示圖片 第一個參數(shù)為窗口名 第二個為讀取的圖片變量
cv2.imshow('img',img)
cv2.imshow('gray',img1)
cv2.imshow('cover',cover)
cv2.waitKey(0)
cv2.destroyAllWindows()
image
#直方圖規(guī)定化

import cv2

import numpy as np

import matplotlib.pyplot as plt

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

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

#把兩張圖片轉(zhuǎn)成真正的灰度圖片,因為自己只會做灰度圖片的規(guī)定化

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

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

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

mHist1=[]

mNum1=[]

inhist1=[]

mHist2=[]

mNum2=[]

inhist2=[]

#對原圖像進(jìn)行均衡化
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#統(tǒng)計灰度值的個數(shù)

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]))
    
 #對目標(biāo)圖像進(jìn)行均衡化

for i in range(256):

    mHist2.append(0)

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

for i in range(rows):

    for j in range(cols):

        mHist2[scr[i,j]]= mHist2[scr[i,j]]+1#統(tǒng)計灰度值的個數(shù)

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]))
在這里插入圖片描述

  • 幾何變換

函數(shù) 功能
cv2.resize( ) 圖像縮放
cv2.warpAffine( ) 圖像平移
cv2.getRotationMatrix2D( ) cv2.warpAffine( ) 圖像旋轉(zhuǎn)
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()

image

image

image

image
"""圖像金字塔"""

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

[圖片上傳失敗...(image-34aa17-1626678518137)]

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

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

  • 平滑、銳化

函數(shù) 功能
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()

  • 數(shù)學(xué)形態(tài)學(xué)

函數(shù) 功能
cv2.erode( ) 腐蝕
cv2.dilate( ) 膨脹
cv2.morphologyEx(,cv2.MORPH_OPEN) 開運(yùn)算
cv2.morphologyEx(,cv2.MORPH_CLOSE) 閉運(yùn)算
cv2.morphologyEx(,cv2.MORPH_TOPHAT) 頂帽運(yùn)算
cv2.morphologyEx(,cv2.MORPH_BLACKHAT) 底帽運(yùn)算
cv2.morphologyEx(,cv2.MORPH_GRADIENT) 形態(tài)學(xué)梯度
"數(shù)學(xué)形態(tài)學(xué)"

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)

#設(shè)置結(jié)構(gòu)元
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))

#圖像開運(yùn)算處理
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)

#圖像閉運(yùn)算處理
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()
image

  • 閾值分割

函數(shù) 功能
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,) 自適應(yīng)閾值處理
cv2.adaptiveThreshold(,,cv2.ADAPTIVE_THRESH_MEAN_C,) 自適應(yīng)閾值處理
"閾值分割"

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

  • 邊緣檢測

函數(shù) 功能
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)
image

  • 色彩空間

函數(shù) 功能
cv2.cvtColor(,cv2.COLOR_BGR2GRAY) 圖像灰度化
cv2.cvtColor(,cv2.COLOR_BGR2HSV) RGB轉(zhuǎn)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()
image

  • 形狀繪制

函數(shù) 功能
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()
image

image

寫在最后

資料包

下一期將扒拉sklearn庫,該庫是做機(jī)器學(xué)習(xí)的不二之選,歡迎大家搬好小板凳呀!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容