OpenCV сохранить черный PNG

Я пытаюсь написать программу на C ++, которая применяет плоскую область к изображению. Предполагается загрузить изображение и разделить его на другое загруженное изображение, а затем экспортировать как PNG. Моя программа компилируется правильно, но выдает только чёрное изображение.

#include <climits>
#include <stdio.h>
#include <string>
#include <opencv/cv.h>
#include <opencv/highgui.h>

using namespace cv;
using namespace std;

int main( int argc, char *argv[] )
{
const char *flat_file = argv[1];
const char *img_file = argv[2];
const char *out_file = argv[3];

Mat flat_img;
flat_img = imread( flat_file, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH );
Mat image;
image = imread( img_file, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH );

GaussianBlur( flat_img, flat_img, cv::Size(3,3), 0, 0, BORDER_REPLICATE );
divide( image, flat_img, image, 1.0, -1 );
imwrite( out_file, image );

return 0;
}

Все входные файлы имеют 16-битный формат TIFF. В настоящее время результирующий выходной файл представляет собой 16-битный PNG, который имеет правильные размеры в пикселях, но полностью черный.

Я очень плохо знаком с C ++ и OpenCV, поэтому я не совсем уверен, чего мне не хватает. Эта тема кажется, предполагает, что, возможно, значения с плавающей точкой являются причиной. Я в порядке с преобразованием из плавающей запятой, но мне нужно поддерживать 16-битную природу моего источника. Я пытался добавить строку image.convertTo( image, CV_16U ); после команды деления, с обоими CV_16U а также CV_8U и ни один не работает.

Любая помощь очень ценится!

РЕДАКТИРОВАТЬ

Следуя приведенным ниже советам, я попытался добавить несколько команд imshow, чтобы фактически проверить, что opencv правильно обрабатывает данные. Кажется, что все работает нормально до моей команды деления. После этого мой массив изображений становится пустым.

2

Решение

Оказывается, это была действительно моя команда «разделяй». Я основывал свой код на похожем приложении, написанном коллегой, поэтому я пошел и посмотрел, как они делили разделение. Я не уверен на 100%, что это происходит, но это работает, когда я изменяю свою разницу на это:

divide( image, flat_img, image, image.depth() == 16 ? UCHAR_MAX : USHRT_MAX );

Просто сделав прогноз, это условно устанавливает скаляр для моих данных на основе глубины изображения. Один вопрос, который у меня остался, состоит в том, какая разница между тем, что у меня есть, и тем, divide( image, flat_img, image, image.depth() == 8 ? UCHAR_MAX : USHRT_MAX ); было бы. Оба производят то, что кажется одним и тем же изображением. В основном я пытаюсь понять, что происходит немного лучше.

1

Другие решения

Ответ, вероятно, заключается в том, что вы уже правильно поняли изображение, потому что если вы используете обычный браузер изображений для открытия 16-битного изображения, оно обычно полностью затемнено, поскольку они поддерживают только правильное отображение 8-битного изображения.

Чтобы справиться с этим, сначала попытайтесь отобразить 16-битное изображение с помощью OpenCV highgui.
ты можешь сделать imshow("test",image) ; waitKey(0) ; и посмотрите, правильно ли отображается изображение. Если это так, вы можете преобразовать ваше изображение в 8bit Mat img8bit ; image.convertTo(img8bit, CV8U, 255./65535.) ; и напишу этот новый мат.

1