2014-11-14 3 views
1

У меня есть два изображения, которые я вычитание друг от друга довольно просто:Предотвращение потери информации о вычитании изображения

Mat foo, a, b; 
...//imread onto a and b or somesuch 
foo = a - b; 

Теперь, как я понимаю, любое значение пикселя, который переходит в негативов (или более 255 для это значение) вместо этого будет установлено на ноль. Если это так, я хотел бы знать, есть ли способ разрешить ему идти до нуля, чтобы я мог настроить изображение позже без потери информации.

Я работаю с изображениями в оттенках серого, если это упрощает вещи.

+2

вы можете использовать ':: резюме absDiff' функции или вы можете преобразовать в знаковый тип данных (например,' CV_16S') и получить отрицательные значения тоже. – Micka

+0

Звучит достаточно хорошо. Как мне изменить с 8UC1 на 16SC1 (например) и обратно? Или я могу использовать imwrite() без преобразования матрицы обратно в CV_8UC1? Если да, то что происходит с отрицательными значениями, когда я использую imwrite? Хотя я, вероятно, сначала отредактирую изображение. –

+0

попробуйте 'yourMat.convertTo (...)' для преобразования в другой тип. При преобразовании в более ограниченный тип вы можете использовать альфа-и бета-параметры в соответствии с типом limites, иначе будет использоваться заливка насыщенности. http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-convertto Вы можете использовать 'imshow', а значение afaik 0 будет отображаться серым для подписанных типов. Не уверен, что вы можете напрямую использовать 'imwrite', документация говорит, что вы можете использовать только типы' 8U' и '16U', и если они будут работать, вероятно, будет некоторое неинтуитивное преобразование/масштабирование/перевод ваших цветов. Я скоро напишу ответ. – Micka

ответ

1

Это как простой новообращенный => вычесть => convertAndScaleBack приложение будет выглядеть следующим образом:

вход:

enter image description here

и

enter image description here

INT основной() { cv :: Mat input = cv :: imread (".. /inputData/Lenna.png ", CV_LOAD_IMAGE_GRAYSCALE); cv :: Mat input2 = cv :: imread ("../ inputData/Lenna_edges.png", CV_LOAD_IMAGE_GRAYSCALE);

cv::Mat input1_16S; 
    cv::Mat input2_16S; 

    input.convertTo(input1_16S, CV_16SC1); 
    input2.convertTo(input2_16S, CV_16SC1); 

    // compute difference of 16 bit signed images 
    cv::Mat diffImage = input1_16S-input2_16S; 

    // now you have a 16S image that has some negative values 

    // find minimum and maximum values: 
    double min, max; 
    cv::minMaxLoc(diffImage, &min, &max); 
    std::cout << "min pixel value: " << min<< std::endl; 

    cv::Mat backConverted; 

    // scale the pixel values so that the smalles value is 0 and the largest one is 255 
    diffImage.convertTo(backConverted,CV_8UC1, 255.0/(max-min), -min); 

    cv::imshow("backConverted", backConverted);   
    cv::waitKey(0); 
} 

выход:

enter image description here

+0

Для справки, ссылка на [saturate_cast] (http://docs.opencv.org/modules/core/doc/utility_and_system_functions_and_macros.html#saturate-cast), которая используется по умолчанию при кастинге. –

Смежные вопросы