Сдвинутое изображение

Ответить
wowka1319
Участник
Сообщения: 93
Зарегистрирован: 04 дек 2013, 02:14
Репутация: 1

Сдвинутое изображение

Сообщение wowka1319 » 20 фев 2014, 10:26

Формирую изображение:

Код: Выделить всё


uchar *img_data = new uchar[nPixels*nLines*3];
uchar *R = new uchar[nPixels*nLines];
uchar *G = new uchar[nPixels*nLines];
uchar *B = new uchar[nPixels*nLines];
hDstDS->GetRasterBand(1)->RasterIO(GF_Read, 0,0, nPixels, nLines, R, nPixels, nLines, GDT_Byte, 0,0);
hDstDS->GetRasterBand(2)->RasterIO(GF_Read, 0,0, nPixels, nLines, G, nPixels, nLines, GDT_Byte, 0,0);
hDstDS->GetRasterBand(3)->RasterIO(GF_Read, 0,0, nPixels, nLines, B, nPixels, nLines, GDT_Byte, 0,0);

for (quint32 i = 0, j = 0; i < nPixels*nLines; ++i, j+=3)
{
img_data[j] = R;
img_data[j+1] = G;
img_data[j+2] = B;
}
img = new QImage(img_data, nPixels, nLines, QImage::Format_RGB888);


после чего получаю смещенное изображение: [attachment=0]2.png[/attachment]
почему так?
Вложения
2.png
2.png (2.87 МБ) 12720 просмотров

Александр Мурый
Гуру
Сообщения: 5173
Зарегистрирован: 26 сен 2009, 16:26
Репутация: 793
Ваше звание: званий не имею
Откуда: Москва

Re: Сдвинутое изображение

Сообщение Александр Мурый » 20 фев 2014, 11:18

Относительно чего смещённое?
Редактор материалов, модератор форума

wowka1319
Участник
Сообщения: 93
Зарегистрирован: 04 дек 2013, 02:14
Репутация: 1

Re: Сдвинутое изображение

Сообщение wowka1319 » 21 фев 2014, 14:41

ну как же, из картинки видно, что изображение "ушло" влево, и то что вышло за левую рамку пришло с другой (с левой) стороны, как в знаменитом pacman.

Аватара пользователя
nadiopt
Гуру
Сообщения: 4744
Зарегистрирован: 29 янв 2009, 13:27
Репутация: 495
Ваше звание: хрюкало
Откуда: Санкт-Петербург
Контактная информация:

Re: Сдвинутое изображение

Сообщение nadiopt » 21 фев 2014, 14:45

а исходное-то совпадает? может, имеет место смещение одного канала или его неправильное проецирование?
наверное, нужен gdalinfo по всем трем каналам
ин гроссен фамилен нихт клювен клац клац

wowka1319
Участник
Сообщения: 93
Зарегистрирован: 04 дек 2013, 02:14
Репутация: 1

Re: Сдвинутое изображение

Сообщение wowka1319 » 21 фев 2014, 17:29

Упростил код до неприличия. Никакого перепроецирования, просто открыл GeoTiff через GDAL, вытащил каналы и сохранил в PNG:

Код: Выделить всё


CPLSetConfigOption( "GDAL_DATA", "C:/gdal/gdal-data" );

GDALAllRegister();
GDALDataset *srcDataset = (GDALDataset*) GDALOpen("in.tiff", GA_ReadOnly);
int X = srcDataset->GetRasterXSize();
int Y = srcDataset->GetRasterYSize();
int C = srcDataset->GetRasterCount();

GByte *imgData = new GByte[X*Y*C];

srcDataset->GetRasterBand(1)->RasterIO(GF_Read, 0,0, X, Y, imgData, X, Y, GDT_Byte, C, 0);
srcDataset->GetRasterBand(2)->RasterIO(GF_Read, 0,0, X, Y, &imgData[1], X, Y, GDT_Byte, C, 0);
srcDataset->GetRasterBand(3)->RasterIO(GF_Read, 0,0, X, Y, &imgData[2], X, Y, GDT_Byte, C, 0);
GDALClose(srcDataset);

img = new QImage(imgData, X, Y, QImage::Format_RGB888);
img->save("out.png");


в итоге получаю какое-то скошенное изображение. пиксели каждой линии сдвигаются влево, причем чем ниже линия, тем дальше она сдвигается. и то что выходит влево, заходит справа. Я пока не говорю про цвет (почему-то ч/б получается и в полосочку).
Было (пересохранил из GeoTiff в PNG для наглядности):
in.png
in.png (1.2 МБ) 12640 просмотров
Стало:
out.png
out.png (1.26 МБ) 12640 просмотров
P.S: На всякий случай прикладываю GeoTiff:
in.zip
(1.28 МБ) 392 скачивания

gamm
Гуру
Сообщения: 4056
Зарегистрирован: 15 окт 2010, 08:33
Репутация: 1054
Ваше звание: программист
Откуда: Казань

Re: Сдвинутое изображение

Сообщение gamm » 21 фев 2014, 19:33

wowka1319 писал(а):в итоге получаю какое-то скошенное изображение. пиксели каждой линии сдвигаются влево, причем чем ниже линия, тем дальше она сдвигается. и то что выходит влево, заходит справа.
это оттого, что длина строки указана неверно (разница равна сдвигу между строками). Как вы этого добились - ищите, не исключено, что ваша картинка была в девичестве BMP, а там бывает выравнивание длины (фактическая длина не совпадает с указанной). Или еще чего подобное. Печатайте все теги (сделайте дамп), и смотрите, что в них - обычно минут через 20 наступает прозрение :D

Аватара пользователя
Дмитрий Барышников
Гуру
Сообщения: 2572
Зарегистрирован: 17 ноя 2009, 19:17
Репутация: 261
Откуда: Москва

Re: Сдвинутое изображение

Сообщение Дмитрий Барышников » 21 фев 2014, 23:43

Попробуйте так:

Код: Выделить всё


int nPixelSpace(0);
int nLineSpace(0);
int nBandSpace(0);
int nDataSize = GDALGetDataTypeSize(GDT_Byte) * 0.125;
nPixelSpace = nDataSize * C;
nLineSpace = X * nPixelSpace;
nBandSpace = nDataSize;

srcDataset->RasterIO(GF_Read, 0, 0, X, Y, imgData, X, Y, GDT_Byte, C, NULL, nPixelSpace, nLineSpace, nBandSpace);

 
Если не получиться, приложите весь или кусочек тифа в архиве

wowka1319
Участник
Сообщения: 93
Зарегистрирован: 04 дек 2013, 02:14
Репутация: 1

Re: Сдвинутое изображение

Сообщение wowka1319 » 24 фев 2014, 03:26

Код мне не очень понятен. Тем не менее простой копипаст не вызвал проблем - все работает, но точно также, т.е. коряво. Тиф я приложил в предыдущем сообщении (in.zip).

gamm
Гуру
Сообщения: 4056
Зарегистрирован: 15 окт 2010, 08:33
Репутация: 1054
Ваше звание: программист
Откуда: Казань

Re: Сдвинутое изображение

Сообщение gamm » 24 фев 2014, 04:20

wowka1319 писал(а):Код мне не очень понятен. Тем не менее простой копипаст не вызвал проблем - все работает, но точно также, т.е. коряво. Тиф я приложил в предыдущем сообщении (in.zip).
результат (png) забыли приложить. И я попробовал в R, все работает как надо.

Код: Выделить всё

library(rgdal)
# rgdal: version: 0.8-14, (SVN revision 496)
# Geospatial Data Abstraction Library extensions to R successfully loaded
# Loaded GDAL runtime: GDAL 1.10.1, released 2013/08/26

fn.region<-"in.tiff"

# --- Load image

work.region.tif <- new("GDALReadOnlyDataset", fn.region)
p.b<-getRasterTable(work.region.tif)        # by rows, from the upper-left corner
p.bbox<-work.region.tif[,,1]@bbox           # bounding box
p.csize<-work.region.tif[,,1]@grid@cellsize # cell (pixel) size
p.b.prj<-getProjectionRef(work.region.tif)  
p.b.dim<-dim(work.region.tif)               # c(ny,nx,nband)
GDAL.close(work.region.tif)

# --- make output GeoTIFF image (with projection)

p.out<-data.frame(x=p.b[,1],y=p.b[,2],R=p.b[,3],G=p.b[,4],B=p.b[,5])
coordinates(p.out) = ~x+y
gridded(p.out) = TRUE
p.out.grd=as(p.out,"SpatialGridDataFrame")
p.out.grd@proj4string@projargs<-as.character(p.b.prj)
p.out.tif<-create2GDAL(p.out.grd,drivername="GTiff",type="UInt16")
saveDataset(p.out.tif,"out.tif")
GDAL.close(p.out.tif)

16 bit результат, открывается в QGIS
out.jpg
out.jpg (909.79 КБ) 12526 просмотров

wowka1319
Участник
Сообщения: 93
Зарегистрирован: 04 дек 2013, 02:14
Репутация: 1

Re: Сдвинутое изображение

Сообщение wowka1319 » 24 фев 2014, 07:54

Я разобрался в чем дело. Оказывается конструктор
QImage(uchar *data, int width, int height, QImage::Format);
требует выравнивания RGB в 32 бита, т.е. сначала идут три байта цвета, а следом пустой байт. Я немного ошарашен таким требованием, ибо 25% памяти коту под хвост. Видимо тут вступают какие-то оптимизации. Однако есть еще один конструктор:
QImage(uchar *data, int width, int height, int bytesPerLine, QImage::Format);
который позволяет избежать указанные выше издержки по памяти.
И на всякий случай, тем кто в будущем возможно столкнется с подобной проблемой, приведу корректный код:

Код: Выделить всё


CPLSetConfigOption( "GDAL_DATA", "C:/gdal/gdal-data" );

GDALAllRegister();
GDALDataset *srcDataset = (GDALDataset*) GDALOpen("in.tiff", GA_ReadOnly);
int X = srcDataset->GetRasterXSize();
int Y = srcDataset->GetRasterYSize();
int C = srcDataset->GetRasterCount();

GByte *imgData = new GByte[X*Y*C];

srcDataset->GetRasterBand(1)->RasterIO(GF_Read, 0,0, X, Y, imgData, X, Y, GDT_Byte, C, 0);
srcDataset->GetRasterBand(2)->RasterIO(GF_Read, 0,0, X, Y, &imgData[1], X, Y, GDT_Byte, C, 0);
srcDataset->GetRasterBand(3)->RasterIO(GF_Read, 0,0, X, Y, &imgData[2], X, Y, GDT_Byte, C, 0);
GDALClose(srcDataset);

img = new QImage(imgData, X, Y, X*C, QImage::Format_RGB888);
img->save("out.png");


P.S Всем неравнодушным спасибо за помощь.

gamm
Гуру
Сообщения: 4056
Зарегистрирован: 15 окт 2010, 08:33
Репутация: 1054
Ваше звание: программист
Откуда: Казань

Re: Сдвинутое изображение

Сообщение gamm » 24 фев 2014, 08:04

wowka1319 писал(а):Я разобрался в чем дело. Оказывается конструктор
QImage(uchar *data, int width, int height, QImage::Format);
требует выравнивания RGB в 32 бита, т.е. сначала идут три байта цвета, а следом пустой байт. Я немного ошарашен таким требованием
это скорее всего место под альфа-канал. Что скорее всего написано в документации. И сделано это, скорее всего, для "мастеров фотошпа". В общем, RTFM никто не отменял :mrgreen:

wowka1319
Участник
Сообщения: 93
Зарегистрирован: 04 дек 2013, 02:14
Репутация: 1

Re: Сдвинутое изображение

Сообщение wowka1319 » 24 фев 2014, 10:30

всё бы так, но конструктор имеет вполне конкретный аргумент QImage::Format, который однозначно задает формат изображения в том числе и наличие альфа канала. Логично было предположить, что по этому параметру конструктор будет знать: есть ли там 4ый канал или нет и делать своё дело исходя из этого. Тем не менее несмотря на QImage::Format_RGB888 (RTFM: The image is stored using a 24-bit RGB format (8-8-8)), нужно дополнительно ему вдалбливать что количество байтов на линию.
Ладно, открываю новую тему...

Ответить

Вернуться в «GDAL/OGR»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 27 гостей