Я пытаюсь написать программу на 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 правильно обрабатывает данные. Кажется, что все работает нормально до моей команды деления. После этого мой массив изображений становится пустым.
Оказывается, это была действительно моя команда «разделяй». Я основывал свой код на похожем приложении, написанном коллегой, поэтому я пошел и посмотрел, как они делили разделение. Я не уверен на 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 );
было бы. Оба производят то, что кажется одним и тем же изображением. В основном я пытаюсь понять, что происходит немного лучше.
Ответ, вероятно, заключается в том, что вы уже правильно поняли изображение, потому что если вы используете обычный браузер изображений для открытия 16-битного изображения, оно обычно полностью затемнено, поскольку они поддерживают только правильное отображение 8-битного изображения.
Чтобы справиться с этим, сначала попытайтесь отобразить 16-битное изображение с помощью OpenCV highgui.
ты можешь сделать imshow("test",image) ; waitKey(0) ;
и посмотрите, правильно ли отображается изображение. Если это так, вы можете преобразовать ваше изображение в 8bit Mat img8bit ; image.convertTo(img8bit, CV8U, 255./65535.) ;
и напишу этот новый мат.