#image #opencv #image-processing #png
#изображение #opencv #обработка изображений #png
Вопрос:
Я пытаюсь прочитать изображение png с одним каналом и 16-битной глубиной. Впоследствии я нахожу значения пикселей в строке:
//read the image data in the file "MyPic.JPG" and store it in 'img'
Mat img = imread("sir.png", CV_LOAD_IMAGE_ANYDEPTH);
//Iterate through the line along which Intensity profile is required
LineIterator it(img, Point(1,1), Point(20,20), 8);
vector<Vec3b> buf;
for(int i=0; i<it.count; i )
{
buf.push_back( Vec3b(*it) );
it ;
}
//print pixel value on the selected line
cerr << Mat(buf) << endl;
Напечатанные значения всегда являются nos, которые меньше 255:
156, 156, 164; 153, 153, 152; 154, 154, 139; 179, 179, 180; 182, 182, 176; 2
208, 167; 144, 144, 163; 204, 204, 206; 180, 180, 187; 174, 174, 170; 150, 1
162; 154, 154, 170; 157, 157, 181; 181, 181, 159; 164, 164, 152; 130, 130, 1
166, 166, 181; 153, 153, 170; 153, 153, 176; 180, 180, 198]
Это означает, что на самом деле это изображение считывается как 8-битное вместо 16-битного.
Я проверил свое изображение в MATLAB, и я вижу значения, которые действительны для 16 бит, такие как :
d=imread('sir.png');
buf = improfile( d, [1 20], [1 20] )
которое выдает такие выходные данные, как:
65535
40092
39321
39578
46003
46774
53456
37008
52428
46260
44718
38550
39578
40349
46517
42148
33410
42662
39321
39321
Почему мой результат в opencv отличается от фактического? Как мне правильно прочитать изображение, чтобы оно отображало значения в 16 битах?
Обновить
Основываясь на ответе Роджера, я обновил свой код следующим образом:
LineIterator it(img, Point(1,1), Point(20,20), 8);
vector<ushort> buf;
for(int i = 0; i < it.count; i )
{
buf.push_back(img.at<ushort>(it.pos()));
}
cerr << Mat(buf) << endl;
Но теперь ВСЕ мои значения пикселей равны 40092, что неверно по сравнению с выводом MATLAB.
Ответ №1:
Вы используете Vec3b
для обработки пикселей, это разбивает его на 8-битные фрагменты.
Используйте Vec3s
вместо Vec3b
. Это даст вам 16-битные пиксели. Это предполагает, что у вас есть 3 16-битных канала, а не один канал с 16-битными оттенками серого (что, я думаю, вы получите из PNG), и в этом случае вы получили бы доступ, например, через at<ushort>(y,x)
.
LineIterator it(img, Point(1,1), Point(20,20), 8);
vector<ushort> buf;
for(int i = 0; i < it.count; i , it )
{
buf.push_back(img.at<ushort>(it.pos()));
}
Комментарии:
1. итак, каково решение?
2. на самом деле исходное изображение представляет собой одноканальное 16-битное изображение, поэтому Vec3S не работает
3. Не могли бы вы, пожалуйста, поместить фрагмент кода для того, что я использую, вместо vec3b и далее. Мое изображение в одноканальном формате.
4. Это дает 20 одинаковых значений 40092, хотя это справедливо для 16-битного изображения, но неверно, если сравнивать с выводом MATLAB
5. Действительно, 40092 является одним из значений, как вы можете видеть в выходных данных MATLAB. Но почему все значения приходят именно так?