The core operation of OpenCV - the basic operation of the image + the arithmetic operation on the image

The core operation of OpenCV - the basic operation of the image + the arithmetic operation on the image

Basic operations on images include accessing pixel values ​​and modifying them, accessing pixel attributes, setting regions of interest, and splitting/merging image channels. If we want to write better optimized code with OpenCV, it is very important to be proficient in using Numpy (Numpy is an optimized library for fast array calculations)

1. Basic operation of images

1.1 Accessing pixel values ​​and modifying them

We can access the pixel values ​​​​through the horizontal and vertical coordinates. For BGR images, it will return an array of blue, green and red values ​​​​(corresponding to the pixel values ​​​​of each color), and for grayscale images, only its corresponding grayscale

code example

>>> import numpy as np
>>> import cv2 as cv
>>> img = cv.imread('messi5.jpg')
>>> px = img[100,100]
>>> print( px ) [157 166 200]
# 仅访问蓝色像素
>>> blue = img[100,100,0]
>>> print( blue )
157

Of course, we can also directly assign a value to a pixel coordinate in this way to achieve the purpose of modifying the pixel value

We just mentioned that Numpy is an optimized library for fast array calculations, and simply accessing each pixel and modifying it like the above method is very slow and inefficient, so we often don't use this method

But if we need to select pixels in an area, the above method is still very useful, for example, we need to operate the first 4 rows and the last 5 columns, etc., Numpy array provides us with two array methods: arry.item() and arry. itemset(), these two methods are often used to access a single element, but they always return a scalar

# 访问 RED 值
>>> img.item(10,10,2)
59
# 修改 RED 值
>>> img.itemset((10,10,2),100)
>>> img.item(10,10,2)
100

1.2 Accessing pixel attributes

Image attributes include the number of rows, columns and channels, image data type, number of pixels, etc., we just want to access these things

The shape of the image can be accessed via img.shape(), which returns a tuple of rows, columns, and number of channels (if the image is color, it is of course also likely to be a single-channel grayscale image)

The total number of pixels can be obtained by accessing the return value of the img.size() function

The image data type is obtained by img.dtype()

Note : img.dtype() is very important when debugging, because a lot of bugs in OpenCV-Python code are caused by invalid data types

1.3 Set image region of interest ROI

In actual operation processing, we always need to process some specific areas. For example, we need to analyze and process human behavior, then we need to monitor the area where the person is and the area within 1 meter to achieve our goal. Instead of searching the entire image, ROI improves the accuracy and performance of image processing

The code implements copying an ROI to another area of ​​the image

>>> ball = img[280:340, 330:390]
>>> img[273:333, 100:160] = ball

1.4 Splitting and Merging Image Channels

Sometimes we need to modify the monochrome channel. At this time, we will use the segmentation and merging of image channels, such as splitting a BGR image into a single channel.

# 把BGR通道分别拆分在b,g,r
b,g,r = cv.split(img) # 拆分
>>> img = cv.merge((b,g,r)) # 合并(注意这里以元组的形式传参)

Get and modify single-channel pixels

>>> b = img [:, :, 0]
>>> img [:, :, 2] = 0
# 注意这里元组中的0和2指的是通道索引

2. Arithmetic operations on images

This part presents several arithmetic operations on the image: addition, subtraction and bitwise operations. Regarding these operations, we must first master: cv.add() and **cv.addWeighted()** These two functional functions use

2.1 Image addition

We have two ways to achieve the image addition operation. The first is to directly use the built-in cv.add() function of OpenCV. The second way is to use the Numpy library to operate through numpy. must have the same depth and type as the added image, or the second image can be a scalar directly

Note : Here is a point that is easy to overlook. The difference between image addition operations through OpenCV and Numpy is that OpenCV addition is a saturation operation (for example, when the pixel is greater than 255, make it equal to 255), while Numpy addition is a modulo operation (pixel addition When it is greater than 255, this value needs to be modulo 255)

>>> x = np.uint8([250])
>>> y = np.uint8([10])
>>> print( cv.add(x,y) ) # 250+10 = 260 => 255
[[255]]
>>> print( x+y ) # 250+10 = 260 % 256 = 4
[4]

We found that the OpenCV function will give better results

2.2 Image Fusion

Image fusion is essentially image addition, but it can set weight coefficients for the pictures used for addition, so that it has the effect of fusion or transparency

import cv2 as cv
import numpy as np

img1 = cv.imread(r'E:\image\wqw.png')
img2 = cv.imread(r'E:\image\qqq.png')
dst = cv.addWeighted(img1, 0.9, img2, 0.3, 0)
cv.imshow('dst', dst)
cv.waitKey(0)
cv.destroyAllWindows()

insert image description here

2.3 Bitwise operations

Bitwise operations include bitwise AND, OR, NOT, and XOR operations, which are useful in extracting any part of an image, defining and handling non-rectangular ROIs, etc.

We still use an example to learn bitwise operations: put the OpenCV Logo on a picture, but it is not a rectangle, so we cannot use the above-mentioned ROI of the image to process the image, this time bitwise operation it came in handy

import numpy as np
import cv2
from matplotlib import pyplot as plt

# 加载两张图片
img1 = cv2.imread(r'E:\image\wqw.png')
img2 = cv2.imread(r'E:\image\opencv.png')
# 我想把logo放在左上角,所以我创建了ROI
# logo left top
rows, cols, channel = img2.shape
roi = img1[0: rows, 0: cols]  # 获得bg
# mask of logo
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)

# 现在将ROI中logo的区域涂黑
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)

# 仅从logo图像中提取logo区域
img2_fg = cv2.bitwise_and(img2, img2, mask=mask)

# 将logo放入ROI并修改主图像
dst = cv2.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst
cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

emmm I don’t know why my program can’t display the cutout effect, but the idea of ​​the code should be fine

First of all, we need to find the area where we put the Logo in the main image as the ROI, and then find the mask and the opposite mask for our Logo, so that the ROI area and the mask of the Logo can be ANDed, that is, the logo to be placed in the ROI The next step is to cut out our Logo area from the original image through a mask. After cutting out, add the cut out Logp and the ROI of the logo image to get the final result, and then modify it. The ROI in the original image can be


(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/123590254