ye_ol_man
ye_ol_man

Reputation: 37

Why does imwrite on BMP image gets stuck / does not return?

I am reading a Bitmap-file from disk and write a copy back to disk after some manipulation, also writing a copy of the original file. The bitmaps are relatively small with a resolution of 31 x 31 pixel.

What I see is that when I have a resolution of 30 x 30 pixel then cv::imwrite correctly writes out the files, however if I go for a resolution of 31 x 31 pixel then cv:imwrite just gets stuck and does not return. This is happening on the same directories.

<...>
image = cv::imread(imageName, IMREAD_GRAYSCALE); // Read the file
if( image.empty() )                      // Check for invalid input
{
    cout <<  "Could not open or find the image" << std::endl ;
    return -1;
}
Mat image_flip (width,height,CV_8U);

int8_t pixel_8b;
for (int i=0; i< width; i++){
    for (int j=0; j < height; j++){
        pixel_8b= image.at<int8_t>(i,j);
        image_flip.at<int8_t>(width-i,j) = pixel_8b;
    }
}
cout << "Writing files" << endl;
result=cv::imwrite("./output_flip.bmp", image_flip);

cout << result << endl;
return 0;

In the good case I get the file output_flip.bmp written to the disk and result is displayed. In the bad case of being stuck the last thing I see is "Writing files" and then nothing anymore. I can switch back and forth between the good and the bad case by just resizing the input image.

Any ideas how to solve that issue?

Upvotes: 0

Views: 846

Answers (1)

HansHirse
HansHirse

Reputation: 18925

As already discussed in the comments, you didn't provide a minimal, reproducible example (MRE). So, I derived the following MRE from your code, because I wanted to point out several things (and wondered, how your code could work at all):

#include <opencv.hpp>

int main()
{
    cv::Mat image = cv::imread("path/to/your/image.png", cv::IMREAD_GRAYSCALE);

    // cv::resize(image, image, cv::Size(30, 30));

    cv::Mat image_flip(image.size().height, image.size().width, CV_8U);

    for (int i = 0; i < image.size().width; i++) 
    {
        for (int j = 0; j < image.size().height; j++) 
        {
            const uint8_t pixel_8b = image.at<uint8_t>(j, i);
            image_flip.at<uint8_t>(j, image.size().width - 1 - i) = pixel_8b;
        }
    }

    std::cout << "Writing files" << std::endl;
    const bool result = cv::imwrite("./output_flip.bmp", image_flip);

    std::cout << result << std::endl;

    return 0;
}
  • For single channel, 8-bit image (CV_8U), use uint8_t when accessing single pixels.
  • When using .at, please notice, that the syntax is .at(y, x). For square images, it might be equal, but in general, it's a common source for errors.
  • Accessing .at(j, width-i) MUST fail for i = 0, if width = image.size().width, since the last index of image is width - 1.

After correcting these issues, I could run your code without problems for larger images, as well as resized images to 30 x 30 or 31 x 31. So, please have a look, if you can resolve your issue(s) by modifying your code accordingly.

(I'm aware, that the actual issue as stated in the question (hanging imwrite) is not addressed at all in my answer, but as I said, I couldn't even run the provided code in the first place...)

Hope that helps!

Upvotes: 2

Related Questions