I need to read large numbers of images with high speed requirements, and just need to handle the Blue channel of a color image.
If I read image with cv::imread(imgName, CV_LOAD_IMAGE_COLOR);
It will be very long time, so I want to read only one color image channel. How to do it ??? thanks very much !!

- 7,472
- 8
- 36
- 71

- 3
- 1
- 2
-
please add your code example. – Gregor Doroschenko Dec 13 '17 at 08:23
-
1If you know how the image data is stored, then you will not ask such a question. – Kinght 金 Dec 13 '17 at 08:29
-
To load an image, most of them needs to be decoded before having the pixel values... but even if it was raw, it is not possible with opencv... maybe you can do it with an SSD drive to do it faster.... – api55 Dec 13 '17 at 08:32
2 Answers
OpenCV doesn't provide any method to load only a specific channel. However, you have a few options.
Load as color image and extract the channel you need
cv::Mat3b img("path/to/image", cv::IMREAD_COLOR);
cv::Mat1b blue;
cv::extractChannel(img, blue, 0);
This is a little faster than using the split
approach, but you still need to load the color image.
In a preprocessing stage, load all your images (you can use glob to retrieve all images into a folder), extract the blue channel and store it as grayscale. Then you can load the image as grayscale.
// Preprocessing
cv::String folder = "your_folder_with_images/*.jpg";
std::vector<cv::String> filenames;
cv::glob(folder, filenames);
for (size_t i = 0; i < std::filenames.size(); ++i)
{
cv::Mat3b img = cv::imread(filenames[i], cv::IMREAD_COLOR);
cv::Mat1b blue;
cv::extractChannel(img, blue, 0);
cv::imwrite("some/other/name", blue);
}
// Processing
cv::Mat1b blue = imread("path/to/image", cv::IMREAD_UNCHANGED);
You can improve speed by saving / loading the image in binary format:
// Preprocessing
...
matwrite("some/other/name", blue);
// Processing
cv::Mat1b blue = matread("path/to/image");

- 40,887
- 13
- 123
- 202
I think you can not do this, at least with OpenCV. If you check the documentation of cv::imread
you will see that there is no option to read only one color channel:
- IMREAD_UNCHANGED: If set, return the loaded image as is (with alpha channel, otherwise it gets cropped).
- IMREAD_GRAYSCALE: If set, always convert image to the single channel grayscale image.
- IMREAD_COLOR: If set, always convert image to the 3 channel BGR color image.
- IMREAD_ANYDEPTH: If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
- IMREAD_ANYCOLOR: If set, the image is read in any possible color format.
- IMREAD_LOAD_GDAL: If set, use the gdal driver for loading the image.
- IMREAD_REDUCED_GRAYSCALE_2: If set, always convert image to the single channel grayscale image and the image size reduced 1/2.
- IMREAD_REDUCED_COLOR_2: If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2.
- IMREAD_REDUCED_GRAYSCALE_4: If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
- IMREAD_REDUCED_COLOR_4: If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
- IMREAD_REDUCED_GRAYSCALE_8: If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
- IMREAD_REDUCED_COLOR_8: If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
- IMREAD_IGNORE_ORIENTATION: If set, do not rotate the image according to EXIF's orientation flag.
If you want, you can split the channels of a matrix after loading it usin Mat::split
:
Mat src = imread("img.png",CV_LOAD_IMAGE_COLOR); //load image
Mat bgr[3]; //destination array
split(src,bgr);//split source
//Note: OpenCV uses BGR color order
imwrite("blue.png",bgr[0]); //blue channel
imwrite("green.png",bgr[1]); //green channel
imwrite("red.png",bgr[2]); //red channel

- 1,895
- 14
- 36
-
yes, I know mat::split. But i need read images with high speed requirements. – Rice Dec 13 '17 at 08:20
-
So you can explain how to CV_LOAD_IMAGE_GRAYSCALE action. if i read image with CV_LOAD_IMAGE_GRAYSCALE , the speed is improved very stronger. But I need blue channel color to process image, – Rice Dec 13 '17 at 08:23
-
I am afraid my answer cannot go further than this, which is the knowledge that I have. I just posted this information because you were not mentioning that you were aware of it already. If nobody answers your question here, you can try in the [OpenCV forum](http://answers.opencv.org/questions/) as well. – apalomer Dec 13 '17 at 08:26
-
Probably you have another option which is dig through the source code of [`cv::imread`](https://github.com/opencv/opencv/blob/a2120263deefe309dcefeccaf169c9ff1e609caa/modules/imgcodecs/src/loadsave.cpp) and try to see how you can change it and load only what you need. – apalomer Dec 13 '17 at 08:39
-
1I believe this answers the question as written Q- "Can I read in only one channel" A- No – GPPK Dec 13 '17 at 08:46