Запись плавающего изображения в openCv со значениями пикселей больше 1

В настоящее время я работаю над программой, которая должна брать изображения LDR и умножать определенный пиксель на изображении, чтобы их значение пикселей превышало нормальную границу значения 0-255 (0-1) пикселей. Программа, которую я написал, может это сделать, но я не могу записать файл изображения, так как imwrite() в OpenCV удерживает значения в диапазоне 0-255 (0-1), если они больше 255.

Есть ли кто-нибудь, кто знает, как написать изображение с плавающей запятой со значениями пикселей больше 255 (1)

Мой код выглядит так

Mat ApplySunValue(Mat InputImg)
{
 Mat Image1 = imread("/****/.jpg",CV_LOAD_IMAGE_COLOR);

Mat outPutImage;

Image1.convertTo(Image1, CV_32FC3);

for(int x = 0; x < InputImg.cols; x++){
    for(int y = 0; y < InputImg.rows; y++){

        float blue  = Image1.at<Vec3f>(y,x)[0] /255.0f;
        float green = Image1.at<Vec3f>(y,x)[1] /255.0f;
        float red = Image1.at<Vec3f>(y,x)[2] /255.0f ;

        Image1.at<Vec3f>(y,x)[0] = blue;
        Image1.at<Vec3f>(y,x)[1] = green;
        Image1.at<Vec3f>(y,x)[2] = red;

        int pixelValue = InputImg.at<uchar>(y,x);

        if(pixelValue > 254){


            Image1.at<Vec3f>(y,x)[0] = blue * SunMultiplyer;
            Image1.at<Vec3f>(y,x)[1] = green * SunMultiplyer;
            Image1.at<Vec3f>(y,x)[2] = red * SunMultiplyer;    
        }

    }

}

imwrite("/****/Nice.TIFF", Image1 * 255);

namedWindow("Hej",CV_WINDOW_AUTOSIZE);
imshow("hej", Image1);



return InputImg;
}

2 ответа

Решение

В целях хранения следующее более эффективно использует память, чем альтернатива XML / YAML (из-за использования двоичного формата):

// Save the image data in binary format
std::ofstream os(<filepath>,std::ios::out|std::ios::trunc|std::ios::binary);
os << (int)image.rows << " " << (int)image.cols << " " << (int)image.type() << " ";
os.write((char*)image.data,image.step.p[0]*image.rows);
os.close();

Затем вы можете загрузить изображение следующим образом:

// Load the image data from binary format
std::ifstream is(<filepath>,std::ios::in|std::ios::binary);
if(!is.is_open())
    return false;
int rows,cols,type;
is >> rows; is.ignore(1);
is >> cols; is.ignore(1);
is >> type; is.ignore(1);
cv::Mat image;
image.create(rows,cols,type);
is.read((char*)image.data,image.step.p[0]*image.rows);
is.close();

Например, без сжатия трехканальное изображение с плавающей точкой 1920x1200 занимает 26 МБ при хранении в двоичном формате, а при хранении в формате YML - 129 МБ. Эта разница в размерах также влияет на время выполнения, поскольку количество обращений к жесткому диску сильно различается.

Теперь, если вам нужно визуализировать изображение HDR, у вас нет другого выбора, кроме как преобразовать его в LDR. Это называется "тональным отображением" ( запись в Википедии).

Насколько я знаю, когда opencv пишет с помощью imwrite, он пишет в формате, поддерживаемом контейнером изображений, и по умолчанию это 255. Однако, если вы просто хотите сохранить данные, вы можете записать объект Mat в XML / YAML файл.

//Writing
cv::FileStorage fs;
fs.open(filename, cv::FileStorage::WRITE);
fs<<"Nice"<<Image1;

//Reading
fs.open(filename, cv::FileStorage::READ);
fs["Nice"]>>Image1;

fs.release(); //Very Important
Другие вопросы по тегам