Opencv study notes - image processing (2)


1. Image gradient-Sobel operator

Image gradient :
Image gradient refers to the rate of change of a certain pixel of the image in the x and y directions (compared with adjacent pixels). It is a two-dimensional vector consisting of two components: the change of the X axis and the change of the Y axis. The image gradient can regard the image as a two-dimensional discrete function, and the image gradient is actually the derivative of this two-dimensional discrete function. The edge of the image is generally realized by performing gradient operations on the image.
Sobel operator :
insert image description here
function:

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)

src : the current image
ddepth : the depth of the image, usually -1
dx : the horizontal direction
dy : the vertical direction
ksize : the size of the Sobel operator

Calculate the horizontal direction:

import cv2 #opencv读取的格式是BGR
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('D:\pie.png')
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
#cv2.CV_64F:图像中超出255的或者小于0的像素点不会被截断,而是保留
sobelx = cv2.convertScaleAbs(sobelx)
#白到黑是正数,黑到白就是负数了,所有的负数会被截断成0,所以要取绝对值
cv_show(sobelx,'sobelx')

Effect:
insert image description here
Calculate the vertical direction, modify the above code:

sobelx = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)

Effect: insert image description here
Calculate the horizontal and vertical directions separately, and then sum

import cv2 #opencv读取的格式是BGR
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('D:\pie.png')
sobelx = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
#cv2.CV_64F:图像中超出255的或者小于0的像素点不会被截断,而是保留
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
#白到黑是正数,黑到白就是负数了,所有的负数会被截断成0,所以要取绝对值
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
#sobelx为水平方向,sobely为垂直方向,0.5权重,0是偏置项
cv_show(sobelxy,'sobelxy')

Effect:
insert image description here
The above processing can be processed in two directions at the same time. When it is necessary to highlight the edge information of a certain direction of the image, it can also only be processed in one direction. It is not recommended to calculate directly, and the effect of separate calculation is better.

2. Image gradient-Scharr operator, laplacian operator


insert image description here
It can be seen from the Scharr operator that the value of the Scharr operator core is larger than that of the Sobel operator, so the Scharr operator is an enhancement of the difference of the Sobel operator, but the Scharr operator only acts on the kernel with a size of 3, so the two The principles and usage methods of detecting image edges are the same.
Laplacian operator
insert image description here
Laplacian operator According to the principle of image processing, the second derivative can be used for edge detection, because the image is two-dimensional, it needs to be derived in two directions, using the Laplacian operator will make the derivation process become Simple. The Laplacian operator is sensitive to noise points and is usually used together with other methods.

The effect of different operators:

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
#不同算子的差异
img = cv2.imread('D:/cat2.jpg',cv2.IMREAD_GRAYSCALE)
#sobel算子
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
#Scharr算子
#Scharr算子不需要设置核的大小,默认大小为3
scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
#laplacian算子
#laplacian算子是中间的点和周围的点的比较,所以不需要考虑水平和垂直的问题
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)

res = np.hstack((img,sobelxy,scharrxy,laplacian))
cv_show(res,'res')

Effect:
insert image description here

3. Canny edge detection

Canny edge detection algorithm is a multi-level edge detection algorithm developed by John F. Canny in 1986.
Canny edge detection steps:

  1. Use a Gaussian filter to smooth the image and filter out noise.
  2. Computes the gradient strength and direction for each pixel in the image.
  3. Apply Non-Maximum Suppression suppression to eliminate spurious responses from edge detection.
  4. Apply double-threshold (Double-Threshold) detection to identify real and potential edges.
    Gaussian filtering
    Use Gaussian filtering to remove noise points in the image.
    insert image description here
    Gradient and direction
    Calculate the size and direction of the gradient, using the sobel operator
    insert image description here
    non-maximum value suppression to
    traverse the pixels one by one with a kernel, and judge whether the current pixel is the maximum value with the same gradient direction among the surrounding pixels, and according to the judgment The result determines whether to suppress the point. That is to remove the small gradient value and retain the large gradient value.
    insert image description here
    insert image description here
    Double-threshold detection
    sets a small gradient value minval and a large gradient value minval. The gradient value smaller than minval is discarded, and the gradient value larger than maxval is retained. If the connection is greater than minval and smaller than maxval, it is considered to be a boundary. , discarding if none.
    insert image description here
    code:
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('D:/cat.jpg',cv2.IMREAD_GRAYSCALE)
v1=cv2.Canny(img,150,200)
v2=cv2.Canny(img,50,100)
res = np.hstack((v1,v2))
cv_show(res,'res')

Effect (on the left is a large gradient value, on the right is a small gradient value):
insert image description here

4. Image Pyramid

Image pyramid is a kind of multi-scale representation of image, which is an effective but conceptually simple structure to explain images at multiple resolutions. The image pyramid of an image is a set of image resolutions that are gradually reduced in a pyramid shape (bottom-up) and originate from the same original image. It is obtained by down-sampling in steps, and the sampling is stopped until a certain termination condition is reached. We compare layer-by-layer images to a pyramid. The higher the level, the smaller the image and the lower the resolution. The image pyramid can be used for feature extraction at different layers. The features of each layer are different, and the effects are also different.
insert image description here
Gaussian Pyramid
Gaussian Pyramid: Downsampling Method (Downscaling)
insert image description here

Gaussian Pyramid: Upsampling Method (Zoom In)
insert image description here

    import cv2 #opencv读取的格式是BGR
    import numpy as np
    def cv_show(img,name):
        cv2.imshow(name,img)
        cv2.waitKey()
        cv2.destroyAllWindows()
    img = cv2.imread('D:/cat2.jpg')
    up=cv2.pyrUp(img)#放大
    img2=cv2.pyrDown(up)#缩小
    res=np.hstack((img,img2))
    cv_show(res,'comp')

The original image is clearer than the image that is first zoomed in and then zoomed out, because there will be loss in the process of zooming in and zooming out. Effect:
insert image description here
Laplacian Pyramid

Each layer of the Laplacian pyramid uses the input minus the reduced and enlarged imageinsert image description here

import cv2 #opencv读取的格式是BGR
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('D:/cat2.jpg')
down = cv2.pyrDown(img)
down_up = cv2.pyrUp(down)
l_1 = img - down_up
cv_show(l_1,'11')

Effect:
insert image description here

5. Image outline

cv2.findContours(img,mode,method)

Parameter description:
img : input image
mode : contour retrieval mode
1.RETR_EXTERNAL: retrieve only the outermost contour;
2.RETR_LIST: retrieve all contours and save them in a linked list;
3.RETR_CCOMP: retrieve all contours, And organize them into two layers: the top layer is the outer boundary of each part, the second layer is the boundary of the hole;
4.RETR_TREE: retrieve all contours, and reconstruct the entire hierarchy of nested contours;

method : Contour approximation method
1. CHAIN_APPROX_NONE: Output the contour in the form of Freeman chain code, and all other methods output polygons (sequences of vertices).
2.CHAIN_APPROX_SIMPLE: Compress the horizontal, vertical and oblique parts, that is, the function only retains their end parts.

1. Draw the outline

import cv2 #opencv读取的格式是BGR
import numpy as np
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
#使用二值图像。
img = cv2.imread('D:/cat.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#设置图像阈值,超过阈值部分取maxval(最大值),否则取0
ret, thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
'''
检测函数,thresh:输入的二值图像
binary:前面处理的二值图像
contours:轮廓点
hierarchy:层级
'''
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
'''
#1是显示所以轮廓,1是显示第1个轮廓,2是显示第二个轮廓
(0, 0, 255)轮廓颜色,BGR格式
2是轮廓的大小
'''
cv_show(res,'res')

Effect:
insert image description here

2. Contour features

contours[5] indicates the fifth contour

cnt = contours[5]
#面积
area=cv2.contourArea(cnt)
print(area)
#周长,True表示闭合的,False表示不闭合
Perimeter=cv2.arcLength(cnt,True)
print(Perimeter)

3. Contour Approximation

Contour approximation Informally, we take a curve and reduce its vertex count while preserving most of its shape.
Before contour approximation, it is necessary to specify the contour to be approximated, here is contours[2], the larger the value in epsilon = value*cv2.arcLength(cnt,True), the stronger the approximation effect, and if it is too large, it will be approximated to one point.

import cv2 #opencv读取的格式是BGR
import numpy as np
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
#使用二值图像。
img = cv2.imread('D:/mouse.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#设置图像阈值,超过阈值部分取maxval(最大值),否则取0
ret, thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[2]
draw_img = img.copy()
res1 = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
draw_img2 = img.copy()
epsilon = 0.01*cv2.arcLength(cnt,True)
#轮廓近似
approx = cv2.approxPolyDP(cnt,epsilon,True)
res2 = cv2.drawContours(draw_img2, [approx], -1, (255, 0, 0), 2)
res = np.hstack((res1,res2))
cv_show(res,'res')

Effect:
insert image description here

4. Bounding rectangle

cv2.boundingRect(cnt) returns the xy coordinates of the center point of the bounding box of the current contour and the width and height of the picture, that is, x, y, w, h.

import cv2 #opencv读取的格式是BGR
import numpy as np
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
#使用二值图像。
img = cv2.imread('D:/mouse.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#设置图像阈值,超过阈值部分取maxval(最大值),否则取0
ret, thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[2]
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv_show(img,'img')

Effect:
insert image description here

5. Circumscribed circle

import cv2 #opencv读取的格式是BGR
import numpy as np
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
#使用二值图像。
img = cv2.imread('D:/contours.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#设置图像阈值,超过阈值部分取maxval(最大值),否则取0
ret, thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[2]
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2)
cv_show(img,'img')

Effect:
insert image description here

Guess you like

Origin blog.csdn.net/Thousand_drive/article/details/124572612