第三章 Opencv3處理圖像python
1 不一樣色彩空間的轉換app
計算機視覺中三種常見的色彩空間:ide
灰度函數
BGR工具
HSV(hue色調 saturation飽合度 value黑暗程度)ui
2 傅里葉變換spa
快速傅里葉變換fftcode
離散傅里葉變換dftorm
高通濾波器heigh passfilter視頻
檢測圖像的某個區域,根據像素和周圍像素的亮度差值來提高該像素亮度的濾波器
示例代碼以下:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2016/11/29 12:23 # @Author : Retacn # @Site : 高通濾波器 # @File : heighPassFilter.py # @Software: PyCharm import cv2 import numpy as np from scipy import ndimage #自定義核 kernel_3x3 = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]) kernel_5x5 = np.array([[-1, -1, -1, -1, -1, ], [-1, 1, 2, 1, -1], [-1, 2, 4, 2, -1], [-1, 1, 2, 1, -1], [-1, -1, -1, -1, -1]]) #讀入圖像,轉換爲灰度格式 img=cv2.imread('../test.jpg',cv2.IMREAD_GRAYSCALE) #卷積 k3=ndimage.convolve(img,kernel_3x3) k5=ndimage.convolve(img,kernel_5x5) #高經過濾 blurred=cv2.GaussianBlur(img,(11,11),0) g_hpf=img-blurred #顯示圖像 cv2.imshow('3x3',k3) cv2.imshow('5x5',k5) cv2.imshow('g_hpf',g_hpf) cv2.waitKey() cv2.destroyAllWindows()
低通濾波器low pass filter
在像素與周圍像素的亮度差值小於一個特定值時,平滑該像素的亮度
3 建立模塊
Filters.py文件,示例代碼以下:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2016/11/29 12:58 # @Author : Retacn # @Site : 濾波器 # @File : filters.py.py # @Software: PyCharm import cv2 import numpy as np import Three.utils #自定義工具類
Utils.py文件
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2016/11/29 12:59 # @Author : Retacn # @Site : 工具類 # @File : utils.py.py # @Software: PyCharm import cv2 import numpy as np from scipy import interpolate
4 邊緣檢測
經常使用函數
def Laplacian(src,
ddepth,
dst=None,
ksize=None,
scale=None,
delta=None,
borderType=None)
def Sobel(src,
ddepth,
dx,
dy,
dst=None,
ksize=None,
scale=None,
delta=None,
borderType=None)
def Scharr(src,
ddepth,
dx,
dy,
dst=None,
scale=None,
delta=None,
borderType=None)
模糊濾波函數
1 平均
函數原型
def blur(src, #源圖像
ksize, #內核大小
dst=None, #輸出圖像
anchor=None, #中心錨點
borderType=None)# 邊界模式
2 高斯模糊
函數原型
def GaussianBlur(src, #輸入圖像
ksize, #高斯濾波模版大小
sigmaX, #橫向濾波係數
dst=None, #輸出圖像
sigmaY=None,#縱向濾波係數
borderType=None)
3 中值模糊
def medianBlur(src, #源圖像
ksize, #中值濾波器的模版的大小
dst=None)#輸出圖像
4 雙邊濾波
def bilateralFilter(src, #輸入圖像
d, #每一個像素鄰域的直徑
sigmaColor, #顏色空間的標準誤差
sigmaSpace, #座標空間的標準誤差
dst=None, #輸出圖像
borderType=None)#邊緣點插值類型
示例代碼以下:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2016/11/29 12:58 # @Author : Retacn # @Site : 濾波器 # @File : filters.py.py # @Software: PyCharm import cv2 import numpy as np import Three.utils #自定義工具類 def strokeEdges(src, dst, blurKsize=7,#中值濾波ksize edgeKsize=5):#Laplacian算子ksize if blurKsize>=3: #中值濾波 blurredSrc=cv2.medianBlur(src,blurKsize) #修改成灰度顏色空間 graySrc=cv2.cvtColor(blurredSrc,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)
5 用定製內核做卷積
def filter2D(src, #輸入圖像
ddepth, #圖像深度
kernel, #卷積核,單通道浮點矩陣
dst=None, #輸出圖像
anchor=None, #一個被濾波的點在覈內的位置(中心)
delta=None,
borderType=None)#邊界類型
若是要對每一個通道使用不一樣的核,必須用split()和merge()
示例代碼以下:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2016/11/29 12:58 # @Author : Retacn # @Site : 濾波器 # @File : filters.py.py # @Software: PyCharm import cv2 import numpy as np import Three.utils # 自定義工具類 # 通常的卷積濾波器 class VConvolutionFilter(object): def __init__(self, kernel): self._kernel = kernel def apply(self, src, dst): cv2.filter2D(src, -1, self._kernel, dst) # 特定的銳化濾波器 class SharpenFilter(VConvolutionFilter): def __init__(self): kernel = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]]) VConvolutionFilter.__init__(self, kernel) # 邊緣檢測濾波器 class FindEdgesFilter(VConvolutionFilter): def __init__(self): kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]) VConvolutionFilter.__init__(self, kernel) # 模糊濾波器 class BlurFilter(VConvolutionFilter): def __init__(self): kernel = np.array([[0.04, 0.04, 0.04, 0.04, 0.04], [0.04, 0.04, 0.04, 0.04, 0.04], [0.04, 0.04, 0.04, 0.04, 0.04], [0.04, 0.04, 0.04, 0.04, 0.04], [0.04, 0.04, 0.04, 0.04, 0.04]]) VConvolutionFilter.__init__(self, kernel) # 脊狀和浮雕效果 class EmbossFilter(VConvolutionFilter): def __init__(self): kernel = np.array([[-2, -1, 0], [-1, 1, 1], [0, 1, 2]]) VConvolutionFilter.__init__(self, kernel) def strokeEdges(src, dst, blurKsize=7, # 中值濾波ksize edgeKsize=5): # Laplacian算子ksize if blurKsize >= 3: # 中值濾波 blurredSrc = cv2.medianBlur(src, blurKsize) # 修改成灰度顏色空間 graySrc = cv2.cvtColor(blurredSrc, 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)
6 修改應用
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/11/28 14:45
# @Author : Retacn
# @Site : cameo實現,有兩種啓動方法: run() 和 onkeypress()
# @File : cameo.py
# @Software: PyCharm
import cv2
from Three import filters
from Two.cameo.managers importWindowManager,CaptureManager
class Cameo(object):
def __init__(self):
self._windowManager=WindowManager('Cameo',self.onkeypress)
self._captureManager=CaptureManager(cv2.VideoCapture(0),self._windowManager,True)
# self._curveFilter=filters.BGRPortraCurveFilter()
def run(self):
self._windowManager.createWindow()
while self._windowManager.isWindowCreated:
self._captureManager.enterFrame()
frame=self._captureManager.frame
# filters.strokeEdges(frame,frame)
# self._curveFilter.apply(frame,frame)
self._captureManager.exitFrame()
self._windowManager.processEvents()
def onkeypress(self,keycode):
'''
space-> 載圖
tab->啓動和中止視頻錄製
esc->退出應用
:param keycode:
:return:
'''
if keycode==32:#space
self._captureManager.writeImage('screenshot.png')
elif keycode==9:#tab
if not self._captureManager.isWritingVideo:
self._captureManager.startWritingVideo('screencast.avi')
else:
self._captureManager.stopWritingVideo()
elif keycode==27:#esc
self._windowManager.destroyWindow()
if __name__=='__main__':
Cameo().run()
7 canny邊緣檢測
示例代碼以下:
import cv2 import numpy as np #讀入灰度圖像 img=cv2.imread('../test.jpg',cv2.IMREAD_GRAYSCALE) #邊緣檢測 cv2.imwrite('../canny.jpg',cv2.Canny(img,200,300)) #顯示圖像 cv2.imshow('canny',cv2.imread('../canny.jpg')) cv2.waitKey() cv2.destroyAllWindows()
8 輪廓檢測
import cv2 import numpy as np img=np.zeros((200,200,),dtype=np.uint8) #將指定的區域設爲白色 img[50:150,50:150]=255 #設定閾值 ret,thresh=cv2.threshold(img,127,255,0) #查找輪廓 image,contours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #更換顏色空間 color=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) img=cv2.drawContours(color,contours,-1,(0,255,0),2) cv2.imshow('contours',color) cv2.waitKey() cv2.destroyAllWindows()
9 邊界框,最小矩形和最小閉圓的輪廓
import cv2 import numpy as np img = cv2.pyrDown(cv2.imread('../contours.jpg', cv2.IMREAD_UNCHANGED)) ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY) image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for c in contours: #繪製矩形邊界框 x, y, w, h = cv2.boundingRect(c) cv2.rectangle(img, (x, y), (x + w, x + y), (0, 255, 0), 2) #繪製最小矩形(紅色) rect=cv2.minAreaRect(c) box=cv2.boxPoints(rect) box=np.int0(box) cv2.drawContours(img,[box],0,(0,0,255),3) #繪製小最閉圓 (x,y),radius=cv2.minEnclosingCircle(c) center=(int(x),int(y)) radius=int(radius) img=cv2.circle(img,center,radius,(0,255,0),2) cv2.drawContours(img,contours,-1,(255,0,0),1) cv2.imshow('contours',img) cv2.waitKey() cv2.destroyAllWindows()
10 凸輪廓與douglas-peucker
示例代碼以下:
import cv2 import numpy as np #讀入圖像 img=cv2.pyrDown(cv2.imread('../contours.jpg'),cv2.IMREAD_UNCHANGED) #修改顏色空間,設置閾值 ret,thresh=cv2.threshold(cv2.cvtColor(img.copy(),cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY) #更換顏色空間 black=cv2.cvtColor(np.zeros((img.shape[0],img.shape[1]), dtype=np.uint8), cv2.COLOR_GRAY2BGR) #檢測輪廓 image,contours,hier=cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: #輪廓的周長 epsilon=0.01*cv2.arcLength(cnt,True) approx=cv2.approxPolyDP(cnt,epsilon,True) hull=cv2.convexHull(cnt) cv2.drawContours(black,[cnt],-1,(0,255,0),2)#綠,精確的輪廓 cv2.drawContours(black,[approx],-1,(255,255,0),2)#藍色 近似多邊形 cv2.drawContours(black,[hull],-1,(0,0,255),2)#紅 cv2.imshow('hull',black) cv2.waitKey() cv2.destroyAllWindows()
11 直線和圓檢測
函數原型:
def HoughLinesP(image, #源圖像
rho, #線段的幾何表示1
theta, #np.pi/180
threshold, #閾值
lines=None,
minLineLength=None, #最小直線長度
maxLineGap=None)#最大線段間隙
直線檢測,示例代碼以下:
import cv2 import numpy as np #讀入圖像 img=cv2.imread('../contours.jpg') #轉換顏色空間 gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #邊緣檢測 edges=cv2.Canny(gray,50,120) #最小直線長度 minLineLength=100 #最大線段間隙 maxLineGap=5 #直線檢測 lines=cv2.HoughLinesP(edges,#須要處理的圖像 1, np.pi/180, 100, minLineLength, maxLineGap) for x1,y1,x2,y2 in lines[1]: cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2) #顯示圖像 cv2.imshow('edges',edges) cv2.imshow('lines',img) cv2.waitKey() cv2.destroyAllWindows()
圓檢測,示例代碼以下:
import cv2 import numpy as np #讀入圖像 img=cv2.imread('../circles.jpg') #更換顏色空間 gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #中值邊濾 imgMb=cv2.medianBlur(gray,5) #圓檢測 circles=cv2.HoughCircles(imgMb, cv2.HOUGH_GRADIENT, 1, 120, param1=100, param2=30, minRadius=0, maxRadius=0) circles=np.uint16(np.around(circles)) for i in circles[0,:]: cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2) cv2.circle(img,(i[0],i[1]),2,(0,0,255),3) cv2.imwrite('../houghCircles.jpg',img) cv2.imshow('../houghCircles.jpg',img) cv2.waitKey() cv2.destroyAllWindows()
12 檢測其餘形狀
能夠使用approxPloyDP
Cv2.findContours和cv2.approxyDP