通過OpencvFor edge detection can be said to be very common,Let's talk about how to usepython opencvStep by step implementation edge detection
pic = cv2.imread(file_path, flag=None)
參數:
返回值:
注意:結果可能與 cvtColor() 的輸出不同.Codec with OpenCV 圖像(libjpeg、默認使用 libpng、libtiff 和 libjasper).因此,OpenCV 始終可以讀取 JPEG、PNG、TIFF.而LinuxNeed to be installed with the operating system image provided by the codeclibjpeg-dev
cap = cv2.VideoCapture(CAMERA_ID)
參數
返回值
ret, frame = cap.read()
返回值
gs_frame=cv2.GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
說明:The source image with gaussian kernel specified convolution
參數
OpenCV中的inRange()函數可實現二值化功能(這點類似threshold()函數inRange_hsv=cv2.inRange((InputArray src, InputArray lowerb,InputArray upperb, OutputArray dst)
參數
返回值
img_erosion=cv2.erode(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None)
說明:Through the use of specific structure element erosion image.This function is used to determine the structure element specified erosion source images,Take the shape of the minimum value of the pixel neighborhood.侵蝕可以應用幾次(迭代),對於多通道圖像,每個通道都是獨立處理的.
參數
返回值
說明:通過使用特定的結構元素來擴大圖像.The function using the specified structure element to extend the source image,該結構元素確定取最大值的像素鄰域的形狀.dilate_img=cv2.dilate(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None)
參數
返回值
morphologyEx_frame=cv2.morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None)
說明:Use the corrosion and expansion to perform advanced morphological transform,After open operation is the first corrosion expansion
參數
返回值
sobel算子簡介:sobel算子認為,鄰域的像素對當前像素產生的影響不是等價的,所以距離不同的像素具有不同的權值,對算子結果產生的影響也不同.一般來說,距離越遠,產生的影響越小.
sobel算子原理: 對傳進來的圖像像素做卷積,卷積的實質是在求梯度值,或者說給了一個加權平均,其中權值就是所謂的卷積核;然後對生成的新像素灰度值做阈值運算,以此來確定邊緣信息.x方向的梯度會加強圖像水平方向的特征,而y方向的梯度會加強圖像豎直方向的特征
sobel=cv2.Sobel(src, ddepth, dx, dy, dst=None, ksize=None, scale=None, delta=None, borderType=None)
說明:Sobel 算子結合了高斯平滑和微分,So the result is more or less resistant to noise.大多數情況下,函數被調用( xorder = 1, yorder = 0, ksize = 3)或 ( xorder = 0, yorder = 1, ksize = 3) 計算第一個 x 或 y 圖像導數.
參數
dst=cv2.convertScaleAbs(src, dst=None, alpha=None, beta=None)
說明:由於sobelOperator to calculate the value of the produce negative,Otherwise the negative will all as0處理,So you want to use the absolute value function.在輸入數組的每個元素上,函數 convertScaleAbs依次執行三個操作:縮放、取絕對值,轉換為無符號 8 位類型.在多通道數組的情況下,The function to deal with each channel independently.When the output is not 8 位時,Operation can be by calling Mat::convertTo 方法(Or use the matrix expression),And then the calculation results of absolute value.
參數
add_weight_img=cv2.addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=None)
說明:計算兩個數組的加權和: dst = src1alpha + src2beta + gamma
參數
scharr_img=cv2.Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None)
說明:雖然SobelOperator can effectively extract the image edge,但是對圖像中較弱的邊緣提取效果較差.So in order to effectively extract the edge of the weak,Need to increase the gap between the pixel values.Scharr算子是對Sobel算子差異性的增強,因此兩者之間的在檢測圖像邊緣的原理和使用方式上相同.Scharr算子的邊緣檢測濾波的尺寸為3×3,因此也有稱其為Scharr濾波器.可以通過將濾波器中的權重系數放大來增大像素值間的差異.
參數
canny_img=cv2.Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
說明:Found in the input image edge,And use the canny algorithm.阈值 1 和阈值 2 之間的最小值用於邊緣鏈接.This strong used to find the edge of the initial period of maximum.
參數
contours, hierarchy=cv2.findContours(image, mode, method, contours=None, hierarchy=None, offset=None):
說明:從二進制圖像中檢索輪廓.
參數
image:一般為sobel算子或者scharrOperator to get binary image.8 位單通道圖像.非零像素被視為 1.零像素保持為 0,因此圖像被視為 binary
mode:
method
contours:The outline of detection array,每一個輪廓用一個point類型的vector表示
hierarchy:The same number and profile,每個輪廓contours[ i ]對應4個hierarchy元素hierarchy[ i ][0 ] ~hierarchy[ i ][ 3],分別表示後一個輪廓、前一個輪廓、父輪廓、內嵌輪廓的索引編號,如果沒有對應項,該值設置為負數.
offset:每個輪廓點移動的可選偏移量
返回值
cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
說明:繪制輪廓輪廓或填充輪廓
參數
源代碼:
import cv2
import numpy as np
# Select images detection or choose the video
is_picture = True
file_path = '../Picture/Badminton.jpeg'
# 識別OpencCVThreshold value of the book:'red': {'Lower': np.array([0, 53, 66]), 'Upper': np.array([74, 76, 187])
# This is the colorHSV的范圍值(分別代表的是H,S,V),可以根據需求進行刪改
color_dist = {
'red': {
'Lower': np.array([0, 53, 66]), 'Upper': np.array([74, 76, 187])},
'blue': {
'Lower': np.array([100, 80, 46]), 'Upper': np.array([124, 255, 255])},
'green': {
'Lower': np.array([77, 54, 47]), 'Upper': np.array([166, 255, 255])},
'yellow': {
'Lower': np.array([26, 43, 46]), 'Upper': np.array([34, 255, 255])},
}
class DetectProcess(object):
def __init__(self):
super(DetectProcess, self).__init__()
# Corrosion morphology operation:cv2.erode
def erode(self, img):
# Create corrosion use kernel:3x3和5x5
kernel = np.ones((3, 3), np.uint8)
# 執行腐蝕操作 iterationsThe number of execution of corrosion
img_erosion = cv2.erode(img, kernel, iterations=1)
return img_erosion
# 形態學膨脹:cv2.dilate
def dilate(self, img):
kernel = np.ones((5, 5), np.uint8)
dilation = cv2.dilate(img, kernel, iterations=1)
return dilation
# 開運算:cv2.morphologyEx() :先腐蝕再膨脹,有助於消除噪音.
def morphologyExOpening(self, img):
kernel = np.ones((5, 5), np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
return opening
# 閉運算:Used to eliminate the foreground object or objects of holes on the little black spots
def morphologyExClosing(self, img):
kernel = np.ones((5, 5), np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
return closing
# sobel算子:The returned image channel is the same as the original,After the color image processing is still3通道
# sobelThe image is there are a number of smaller
def sobel(self, img):
# The scope of kernel function is:1,3,5,7,9,Effect of kernel function is too bad
Ksize = 3
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=Ksize)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=Ksize)
# sobel-x方向
sobel_X = cv2.convertScaleAbs(sobelx)
# sobel-y方向
sobel_Y = cv2.convertScaleAbs(sobely)
# sobel-xy方向
sobel_XY = cv2.addWeighted(sobel_X, 0.5, sobel_Y, 0.5, 0)
return sobel_XY
# Scharr算子:The returned image channel is the same as the original,After the color image processing is still3通道
def scharr(self, img):
scharr_x = cv2.Scharr(img, cv2.CV_8U, 1, 0)
scharr_y = cv2.Scharr(img, cv2.CV_8U, 0, 1)
scharrX = cv2.convertScaleAbs(scharr_x)
scharrY = cv2.convertScaleAbs(scharr_y)
scharr_XY = cv2.addWeighted(scharrX, 0.5, scharrY, 0.5, 0)
return scharr_XY
# Canny:Return for single channel image
# Get is a light color line
def canny(self, img):
# Kernel function values for3,5,7
# 高低阈值maxVal和minVal的取值范圍1-255
# L2g為“精准”標識符,參數為True和False
Ksize = 3
minVal = 20
maxVal = 40
L2g = True
Canny = cv2.Canny(img, minVal, maxVal, apertureSize=Ksize, L2gradient=False)
return Canny
# To outline the area of the screen
def areaFilter(contours):
""" The area of screen,若大於900The edge of the area we considered valid,This can be adjusted according to your needs :param contours: A collection of contour :return: Identify the outline of the effective collection """
areas = []
for i in range(len(contours)):
if cv2.contourArea(contours[i]) <= 900:
continue
else:
areas.append(contours[i])
return areas
# areas.sort()
# print("area is:", areas)
if __name__ == '__main__':
detect = DetectProcess()
# 調用攝像頭
cap = cv2.VideoCapture(0)
while True:
if is_picture:
frame = cv2.imread(file_path)
else:
# 讀取視頻幀,retThe result of mark read,frameTo read the video frame image
ret, frame = cap.read()
# 高斯濾波
gs_frame = cv2.GaussianBlur(frame, (5, 5), 0)
# 轉化成HSV圖像
hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)
# Set the red areasHSV.
# OpenCV中的inRange()函數可實現二值化功能(這點類似threshold()函數
# cv2.inRange((InputArray src, InputArray lowerb,InputArray upperb, OutputArray dst);
# 參數1:輸入要處理的圖像,可以為單通道或多通道.
# 參數2:包含下邊界的數組或標量.
# 參數3:包含上邊界數組或標量.
# 參數4:輸出圖像,與輸入圖像src 尺寸相同且為CV_8U 類型.Can also be used as a return value to deal with
inRange_hsv = cv2.inRange(hsv, color_dist['green']['Lower'], color_dist['green']['Upper'])
cv2.imshow('inRange_hsv', inRange_hsv)
# Corrosion morphology operation
erode_frame = detect.erode(inRange_hsv)
cv2.imshow('erode', erode_frame)
# 形態學膨脹操作
dilate_frame = detect.dilate(erode_frame)
cv2.imshow('dilate', dilate_frame)
# 開運算
morphologyExOpening_frame = detect.morphologyExOpening(inRange_hsv)
cv2.imshow('morphologyExOpening', morphologyExOpening_frame)
# 閉運算
morphologyExClosing_frame = detect.morphologyExClosing(morphologyExOpening_frame)
cv2.imshow('morphologyExClosing', morphologyExClosing_frame)
# Sobel_frame
Sobel_frame = detect.sobel(morphologyExClosing_frame)
cv2.imshow('Sobel_frame', Sobel_frame)
# Looking for external point:建立RETR_EXTERNALTo count the peripheral biggest point.
contours, hierarchy = cv2.findContours(Sobel_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# cnt = contours[1:50] The scope of the said is to extract image
cv2.drawContours(frame, areaFilter(contours), -1, (0, 0, 255), 2)
cv2.imshow('result', frame)
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
效果: