Following the traditional process of software developers learning a new technology, let’s start with a “Hello world” program.
The target
In this tutorial we will learn how to:
- Read an image from a file (using CV ::imread)
- Display an image in an OpenCV window (using CV ::imshow)
- Write an image to a file (using CV ::imwrite)
C + + version
The source code
Downloadable code: Click here
Code overview:
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
int main() {
samples::addSamplesDataSearchPath("/media/data/my_multimedia/opencv-4.x/samples/data");
std::string image_path = samples::findFile("starry_night.jpg");
Mat img = imread(image_path, IMREAD_REDUCED_COLOR_2);
if (img.empty()) {
std::cout << "Could not read the image: " << image_path << std::endl;
return 1;
}
imshow("Display window", img);
int k = waitKey(0); // Wait for a keystroke in the window
if (k == 's') {
imwrite("starry_night.png", img);
}
return 0;
}
Copy the code
The source code that
In OpenCV 4 we have multiple modules. Each of these focuses on a different area or approach to image processing. You may already see this in the user guide structure of the tutorials themselves. Before you can use any of them, you first need to include header files that declare the contents of each individual module.
You will almost always use:
-
Core section, because this is where the basic building blocks of the library are defined
-
Imgcodecs module, which provides functionality for reading and writing
-
Highgui module because it contains the ability to display images in a window
We also include ioStream to facilitate console line output and input.
Using namespace CV; In the code below, library functions can be accessed without explicitly declaring a namespace.
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
Copy the code
Now let’s take a look at the main code. First, we read the image “starry_night.jpg” file from the OpenCV example. To do this, the CV ::imread function is called to load the image using the file path specified by the first argument. The second parameter is optional and specifies the format of the desired image. This value can be:
- IMREAD_COLORLoad images in BGR 8-bit format. This is what we use hereThe default value.
- IMREAD_UNCHANGEDLoad images in their original format (including alpha channels, if available)
- IMREAD_GRAYSCALELoad the image as a grayscale image
- IMREAD_ANYDEPTHReturns a 16 bit /32 bit image if the input has a corresponding depth, otherwise it is converted to 8 bit
- IMREAD_ANYCOLORTo read the color format in any format possible
- IMREAD_LOAD_GDAL, using the GDAL driver to load the image
- IMREAD_REDUCED_GRAYSCALE_2, always turn the image into a single channel grayscale image, and reduce the image size to 1/2 of the original
- IMREAD_REDUCED_COLOR_2, always convert the image to a 3-channel BGR color image, and reduce the image size to 1/2 of the original
- IMREAD_REDUCED_GRAYSCALE_4, always turn the image into a single channel grayscale image, and reduce the image size to 1/4 of the original
- IMREAD_REDUCED_COLOR_4, always convert the image to a 3-channel BGR color image and reduce the image size to 1/4 of the original
- IMREAD_REDUCED_GRAYSCALE_8, always turn the image into a single channel grayscale image, and reduce the image size to 1/8 of the original
- IMREAD_REDUCED_COLOR_8, always convert the image to a 3-channel BGR color image, and reduce the image size to 1/8 of the original
- IMREAD_IGNORE_ORIENTATIONDo not rotate the image according to the direction mark of EXIF.
After reading, the image data will be saved in the CV ::Mat object.
samples::addSamplesDataSearchPath("/media/data/my_multimedia/opencv-4.x/samples/data");
std::string image_path = samples::findFile("starry_night.jpg");
Mat img = imread(image_path, IMREAD_REDUCED_COLOR_2);
Copy the code
The OpenCV source repository contains some test files, which are located under the OpenCV /samples/data directory, and samples::findFile() defaults to looking for files in the current directory. But through samples: : addSamplesDataSearchPath () function, you can add a search for example file search directory. For Eclipse, the default directory in which the program runs is the root of the project, but this can be done by executing the “Working Directory :” TAB under “Arguments” in the configuration.
Note: OpenCV provides support for Windows bitmap (BMP), portable image formats (PBM, PGM, PPM) and Sun Raster (SR, RAS) image formats. You can also load things like JPEG (JPEG, JPG, JPE), JPEG 2000 (JP2 – the encoding name Jasper in CMake), TIFF files (TIFF, TIF) and portable Network graphics (PNG) image formats.
The imread() function, after reading and decoding the file, can also format the file in a way specified by the second argument to the function.
After that, a check is performed to check that the image is loaded correctly.
if (img.empty()) {
std::cout << "Could not read the image: " << image_path << std::endl;
return 1;
}
Copy the code
The image is then displayed using a call to the CV ::imshow function. The first argument is the title of the window, and the second argument is the CV ::Mat object to display.
Since we want our window to display until the user presses a key (otherwise the program will end too quickly), we use the CV ::waitKey function, which takes only one parameter, indicating how long (in milliseconds) to wait for user input. 0 indicates waiting. The return value is the key pressed.
imshow("Display window", img);
int k = waitKey(0); // Wait for a keystroke in the window
Copy the code
Finally, when the “S” key is pressed, the image is written to the file. To do this, the CV ::imwrite function is called with the file path and the CV ::Mat object as arguments.
if (k == 's') {
imwrite("starry_night.png", img);
}
Copy the code
Python version
The source code
Downloadable code: Click here
Code overview:
#! /use/bin/env python import cv2 as cv import sys def main(): cv.samples.addSamplesDataSearchPath("/media/data/my_multimedia/opencv-4.x/samples/data") img = cv.imread(cv.samples.findFile("starry_night.jpg")) if img is None: sys.exit("Could not read the image.") print(img.__class__.__name__) cv.imshow("Display window", img) k = cv.waitKey(0) if k == ord("s"): cv.imwrite("starry_night.png", img) if __name__ == "__main__": main()Copy the code
The source code that
Here’s a look at the conversion between C++ code and Python code. For Python programs, you first need to import the OpenCV Python library. The proper way to do this is to assign it a separate name, CV, which will be used to reference the OpenCV Python library below.
import cv2 as cv
import sys
Copy the code
Later, the process for reading the “starry_night.jpg” file from the OpenCV example is exactly the same as in the C++ version: With the aid of CV. Samples. AddSamplesDataSearchPath () and CV. Samples. FindFile () find file path; Read the file by calling Cv.imread (). The interface and parameters of each function are exactly the same as the C++ version. The Python version of cv.imread() also supports all the loading tag arguments of the C++ version.
The cv.imread() function returns a NUMpy ndarray object.
cv.samples.addSamplesDataSearchPath("/media/data/my_multimedia/opencv-4.x/samples/data")
img = cv.imread(cv.samples.findFile("starry_night.jpg"))
Copy the code
OpenCV supports loading image files in exactly the same format as C++.
After the image file is loaded, perform a check to check that the image is loaded correctly.
if img is None:
sys.exit("Could not read the image.")
print(img.__class__.__name__)
Copy the code
It then displays the image in the window using the cv.imshow() function and waits for the user to press the key via cv.waitKey(0) :
cv.imshow("Display window", img)
k = cv.waitKey(0)
Copy the code
Both interfaces are identical to the C++ version.
Finally, if the user presses “s” to save the file (exactly the same as in the C++ version).
if k == ord("s"):
cv.imwrite("starry_night.png", img)
Copy the code
Done.
See Getting Started with Images