This series of columns will be written in a first-of-its-kind question-and-answer writing format to quickly get you up to speed on OpenCV at the beginner, intermediate, and advanced levels.
6. Different operations for image details in Python OpenCV
The goal of this blog will be to explain to you the disassembly of an image, including the description of image pixels, the acquisition and modification of image attribute information, the
Content related to the ROI of the image target area, and knowledge of image channels (including splitting and merging channels)
These are structured in terms of knowledge withnumpy
The library is very tight, so if you're looking at it from a learning perspective, it's recommended that you stock up on thenumpy
Relevant knowledge.
Reads the pixel values of the modified image
In previous blogs, we have learned how to read an image using the function will suffice, and have mastered the two key parameters of that function.
After reading the image, we can directly use the operation array to get the color of any position of the image, usually the default order of this color is BGR.
The test code is as follows:
import cv2 import as plt src = ("./6_test.jpg") # Get pixel values at 100 x 100 position print(src[100, 100]) ("src", src) ()
Here first get the pixel value of 100 x 100 position.src[100,100]
We will get three values, each corresponding to the value of the BGR channel. Let's mark a pixel on the image with rows=250,cols=470 and then modify the above code to see the BGR values obtained.
import cv2 import as plt src = ("./6_test.jpg") # Note that the format for getting pixel values is [cols,rows]. print(src[250, 470]) ("src", src) ()
Of particular note above is that the format for getting pixel values is[cols,rows]
The columns are in front and the rows are behind.
The above is the BGR value, you can also get the value of only a single channel, the corresponding code is[cols,rows,channel]
, corresponds to the code section as follows:
# Get the blue channel value print(src[250, 470, 0])
The blue channel corresponds to 0, the green channel to 1, and the red channel to 2. Exceeding these three values will result in the following error:
IndexError: index 3 is out of bounds for axis 2 with size 3
Currently if you read a grayscale map directly, such as the following code, the values are the same for all three channels.
import cv2 import as plt src = ("./6_test.jpg", 0) # Note that the format for getting pixel values is [cols,rows]. print(src[250, 470]) ("src", src) ()
There is also a potential coding problem in this area. If a four-channel image is read, i.e., the image has transparency, then the index value of the array can be read up to 3, which means that the following code is correct.
import cv2 import as plt src = ("./", -1) # Note that the format for getting pixel values is [cols,rows]. print(src[250, 470, 3]) ("src", src) ()
src[250, 470, 3]
The value of the transparent channel was successfully read.
We can modify the values for specific pixel points, such as the following code
import cv2 import as plt src = ("./6_test.jpg") # Note that the format for getting pixel values is [cols,rows]. src[250, 470] = [255, 255, 255] ("src", src) ()
Notice where the red arrow in the image below is pointing, a white highlight appears, and using this method, a [pretzel image] can be created.
A potential bug to be aware of in this area is that the number of channels used to read the image determines the number of array elements you copy, for example, the following code will report an error.
import cv2 import as plt src = ("./6_test.jpg") # Note that the format for getting pixel values is [cols,rows]. src[250, 470] = [255, 255, 255, 255] ("src", src) ()
The error messages are all similar, with different hint array dimensions.
ValueError: cannot copy sequence with size 4 to array axis with dimension 3
The last point is that using the above way to manipulate the pixel points of an image is very time consuming, because the pixel point data of an image is very large, and in general if you can use numpy to integrate a good method, don't use this kind of the most clumsy way.
Use numpy to get the channel values, note that this way you get scalar values, if you want to get all the BGR values, you need to use the()
Get in order.
import cv2 import numpy as np src = ("./6_test.jpg") print(src[100, 100]) b = (100, 100, 0) g = (100, 100, 1) r = (100, 100, 2) print(b, g, r) ("src", src) ()
If you wish to set the value, use theitemset
function will do.
((100, 100, 0), 200) print(src[100, 100])
You can arbitrarily find a picture for the corresponding test, running the following results:
[ 31 68 118]
31 68 118
[200 68 118]
Frequently Asked Questions about Image Attributes in OpenCV
For an image, in addition to the pixel matrix, there is a very important element, the attributes of the image, these include rows, columns, channels, data type, number of pixels, image shape, and other elements.
For example, we often use to get the shape of the image, in particular, note that the return content is the number of rows, columns, and channels, and that the return value type is a tuple.
If you read the image, set tight read grayscale map, it will only return the number of rows and columns, accordingly through this value can easily determine the type of image you loaded.
For example, the following code reads the same image in different ways and outputs different shapes of the image.
import cv2 import numpy as np # Select a jpg image that can be read to different channels src1 = ("./", -1) src2 = ("./", 0) src3 = ("./") # Four channels, including transparent channels print() # Grayscale charts print() # Three channels print()
The output can be quickly read out to see if the image is a color or grayscale image.
(397, 595, 4) (397, 595) (397, 595, 3)
utilization It is possible to quickly return the total number of pixels in an image with the following test code:
# Select a jpg image that can be read to different channels src1 = ("./", -1) src2 = ("./", 0) src3 = ("./") # Four channels, including transparent channels print() print() # Grayscale charts print() print() # Three channels print() print()
We still have three different ways of reading, and the number of pixels read are as follows:
(397, 595, 4) 944860 (397, 595) 236215 (397, 595, 3) 708645
Note that grayscale and color images have different numbers of pixels and they are preceded by the following relationship.
Number of pixels in grayscale image = number of rows x number of columns = 397 x 595 = 236215
Number of pixels in color image = number of rows x number of columns x number of channels = 944860 (four channels) / 708645 (three channels)
utilization attribute gets the type of the image as follows:
print()
The values read here, are all the sameuint8
represents an 8-bit image, where it can be remembered that as long as theuint8
format, then the corresponding BGR value is in the range of[0,255]
Between.
When manipulating the value of the above attribute, the following bug occurs. The generic solution for this bug is to check whether the image is read normally, which requires special attention:
AttributeError: 'NoneType' object has no attribute 'shape'
print()
The values read here, are all the sameuint8
represents an 8-bit image, where it can be remembered that as long as theuint8
format, then the corresponding BGR value is in the range of[0,255]
Between.
When manipulating the value of the above attribute, the following bug occurs. The generic solution for this bug is to check whether the image is read normally, which requires special attention:
AttributeError: 'NoneType' object has no attribute 'shape'
To this point this article on Python OpenCV for image details of the different operations of the article is introduced to this, more related to Python OpenCV image content, please search for my previous articles or continue to browse the following related articles I hope you will support me in the future!