Image processing in OpenCV - changing color space + image geometric transformation

Image processing in OpenCV - changing color space + image geometric transformation

This part mainly introduces the change of color space and geometric transformation of image in OpenCV image processing. The change of color space is widely used. In the actual problem of image processing, it is often necessary to transform the image into a single-channel grayscale image. There will be a small example of color tracking in this article for easy understanding. The geometric transformation of an image is a commonplace thing, but there are some new concepts in image processing, such as affine transformation and perspective transformation, let’s go straight to work without talking nonsense!

1. Change the color space

Regarding the change of color space, we need to master two important functions: cv.cvtColor and cv.inRange

1.1 Changing the color space

There are more than 150 color space conversion methods in OpenCV, but we only master the two most widely used ones:

BGR <-> grayscale and BGR <-> HSV

The color conversion function cv.cvtColor() is very simple. Can you just pass in two parameters to it? The first parameter is our image object, and the second parameter represents the type flag we want to convert

For BGR → grayscale conversion we use the flag cv.COLOR_BGR2GRAY. Similarly for BGR → HSV we use the flag cv.COLOR_BGR2HSV

To get other flags, you only need to output all the flag names in the library on the python terminal to view

>>> import cv2 as cv
>>> flags = [i for i in dir(cv) if i.startswith('COLOR_')]
>>> print( flags )

1.2 Color object tracking

We use an example to demonstrate color object tracking, which essentially displays only the colors we require in the displayed video to achieve the effect of tracking colors

Easier to display colors in HSV than in BGR

Code

import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
while(1):
     # 读取帧
     _, frame = cap.read()
     # 转换颜色空间 BGR 到 HSV
     hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
     # 定义HSV中蓝色的范围
     lower_blue = np.array([110,50,50])
     upper_blue = np.array([130,255,255])
     # 设置HSV的阈值使得只取蓝色
     mask = cv.inRange(hsv, lower_blue, upper_blue)
     # 将掩膜和图像逐像素相加
     res = cv.bitwise_and(frame,frame, mask= mask)
     cv.imshow('frame',frame)
     cv.imshow('mask',mask)
     cv.imshow('res',res)
     k = cv.waitKey(5) & 0xFF
     if k == 27:
    	 break
cv.destroyAllWindows()

insert image description here

First, we created a VideoCapture object to capture the video, and then read the video frame by frame through while. In the process of reading the video, we need to screen out the blue color separately, so some operations are required

HSV is easier to display colors than BGR. In order to display better, we choose to use HSV images. This process uses cv.cvtColor() to convert BGR to HSV. There is a very important function cv.inRange() in the code. Function, this function is used to filter images in a given pixel interval, which has three parameters, the first is the current "frame", the second and third parameters are the given pixel interval

There is also a very important function cv.bitwise_and(), which has two main purposes:

  • Extract mask selected area: cv.bitwise_and(img1,img2,mask = mask)

First of all, we need to know that we are a mask. When we process some images, we need to select the part we want to process. How do we determine this part? That is to use a mask mask to cover this area

  • Find the intersection of two pictures: cv.bitwise_and(img1,img2)

This usage is very simple, the two parameters passed in are two image objects, and the returned result is the intersection of these two images

2. Image geometric transformation

For OpenCV's image geometric transformation, it provides two conversion functions: cv.warpAffine() and cv.warpPerspective()

cv.warpAffine takes a 2x3 transformation matrix, while cv.warpPerspective takes a 3x3 transformation matrix as input

2.1 Zoom

Image scaling We can use cv.resize() to reset the size of the image. There are two interpolation methods worth noting, one is cv.INTER_AREA for zooming out, and the other is cv.INTER_CUBIC for scaling

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg')
res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC) 
#或者
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)

2.2 Panning

The translation of the image is done by creating a transformation matrix M, and we need to use the function cv.wrapAffine()

We put the transformation matrix into a Numpy array of type np.float32 and pass it to the cv.wrapAffine() function

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()

insert image description here

The parameters of the cv.wrapAffine() function: the first is the displayed image, the second is the transformation matrix, and the third is the size of the image

2.3 Rotation

The rotation of the image also requires a transformation matrix, which we get through the **cv.getRotationMatrix2D()** function, which needs to pass three parameters, the first parameter is the coordinates of the rotation position, which passes a binary The second parameter is the rotation angle, and the third parameter is the parameter used for adjustment. If 1 is passed in, it will rotate in the normal counterclockwise direction. If 0 is passed in, the picture will not be displayed. If 0 is passed in, the picture will not be displayed. Entering -1 will display the result of clockwise rotation

import numpy as np
import cv2 as cv

# cols-1 和 rows-1 是坐标限制
img = cv.imread(r'E:\image\wqw.png', 0)
rows, cols = img.shape
M = cv.getRotationMatrix2D(((cols - 1) / 2.0, (rows - 1) / 2.0), 90, 1)
dst = cv.warpAffine(img, M, (cols, rows))
cv.imshow('img', dst)
cv.waitKey(0)
cv.destroyAllWindows()

insert image description here

2.4 Affine Transformation

Remember the other function cv.getAffineTransform we talked about above? Now we're going to start using it

In an affine transformation, all parallel lines in the original image will remain parallel in the output image. To find the transformation matrix, we need the positions of three points in the input image, and then use the cv.getAffineTransform() function to create a 2* 3 matrix, and then pass it to cv.wrapAffine() to complete the affine transformation

img = cv.imread('drawing.png')
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
dst = cv.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')

insert image description here

2.5 Perspective transformation

For perspective transformation, a 3x3 transformation matrix is ​​required, even after the transformation, straight lines will remain straight, to find this transformation matrix, you need 4 points on the input image (out of these four points, three of them should not be collinear )

The transformation matrix can be found by the function cv.getPerspectiveTransform . Then apply cv.warpPerspective to this 3x3 transformation matrix

img = cv.imread('sudoku.png')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

insert image description here


(Note: For the content of the article, refer to the official Chinese document of OpenCV4.1)
If the article is helpful to you, remember to support it with one click and three links

Guess you like

Origin blog.csdn.net/qq_50587771/article/details/123596875