Почему imwrite на BMP изображение застревает / не возвращается? - PullRequest
0 голосов
/ 13 февраля 2020

Я читаю Bitmap-файл с диска и после некоторой манипуляции записываю копию обратно на диск, а также записываю копию исходного файла. Растровые изображения относительно малы с разрешением 31 x 31 пикселя.

Я вижу, что когда у меня разрешение 30 x 30 пикселя, cv::imwrite правильно записывает файлы, однако, если я go для разрешения 31 x 31 пиксель cv:imwrite просто застревает и не возвращается. Это происходит в тех же каталогах.

<...>
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;

В хорошем случае я получаю файл output_flip.bmp, записанный на диск, и отображается result. В плохом случае застревания последнее, что я вижу, это «Запись файлов», а затем ничего больше. Я могу переключаться между хорошим и плохим случаем, просто изменяя размер входного изображения.

Есть идеи, как решить эту проблему?

1 Ответ

2 голосов
/ 13 февраля 2020

Как уже обсуждалось в комментариях, вы не предоставили минимальный воспроизводимый пример (MRE). Итак, я извлек следующую MRE из вашего кода, потому что хотел указать на несколько вещей (и удивился, как ваш код вообще мог работать):

#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;
}
  • Для одного канала, 8- битное изображение (CV_8U), используйте uint8_t при доступе к отдельным пикселям.
  • При использовании .at обратите внимание, что синтаксис .at(y, x). Для квадратных изображений оно может быть равным, но в целом это общий источник ошибок.
  • Доступ к .at(j, width-i) ДОЛЖЕН быть неудачным для i = 0, если width = image.size().width, так как последний индекс image is width - 1.

После исправления этих проблем я мог без проблем запустить ваш код для больших изображений, а также для изображений с измененным размером до 30 x 30 или 31 x 31. Поэтому, пожалуйста, посмотрите, можете ли вы решить свою проблему (проблемы), изменив свой код соответствующим образом.

(я знаю, что фактическая проблема, как указано в вопросе (висит imwrite), в моем ответе вообще не упоминается, но, как я уже сказал, я даже не смог запустить предоставленный код в первую очередь ...)

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...