我正在尝试使用libraw库加载RAW格式(尤其是Nikon .NEF),然后将其转换为opencv格式cv::Mat
。
过去有人解决了这个问题吗?我该怎么做?
答案 0 :(得分:1)
我有一个从libraw到QImage
(Qt)的转换方法。但是,这证明了libraw的使用,应该很容易适应cv::Mat
。
我的解决方案与此类似:https://github.com/mardy/qtraw/blob/master/src/raw-io-handler.cpp
由于对原始问题的评论中有未解决的问题,请进一步评论:您可以使用libraw控制白平衡,色彩偏差,失真校正等等:http://www.libraw.org/docs/API-datastruct-eng.html#libraw_output_params_t
将嵌入式RAW缩略图从libraw转换为QImage
:
LibRaw RawProcessor;
QImage thumbnail;
if( LIBRAW_SUCCESS == RawProcessor.open_file(filename)) {
if( LIBRAW_SUCCESS == RawProcessor.unpack_thumb() ) {
if (LIBRAW_THUMBNAIL_JPEG == RawProcessor.imgdata.thumbnail.tformat ) {
thumbnail.loadFromData((uchar*)RawProcessor.imgdata.thumbnail.thumb,
RawProcessor.imgdata.thumbnail.tlength,
"JPEG");
LibRawImagePerformFlip(RawProcessor.imgdata.sizes.flip, thumbnail);
} else if (LIBRAW_THUMBNAIL_BITMAP == RawProcessor.imgdata.thumbnail.tformat) {
thumbnail = LibRawImageToQImage(
(uchar*)RawProcessor.imgdata.thumbnail.thumb,
RawProcessor.imgdata.thumbnail.twidth,
RawProcessor.imgdata.thumbnail.theight,
RawProcessor.imgdata.thumbnail.tcolors);
} // else: could not read
}
RawProcessor.recycle();
}
将完整的RAW图像从libraw转换为QImage
:
LibRaw RawProcessor;
QImage image;
RawProcessor.imgdata.params.gamm[0] = 1.0;
RawProcessor.imgdata.params.gamm[1] = 0.0;
RawProcessor.imgdata.params.user_qual = 0; // fastest interpolation (linear)
RawProcessor.imgdata.params.use_camera_wb = 1;
if( LIBRAW_SUCCESS == rawProcessor.open_file(filename) {
if( LIBRAW_SUCCESS == RawProcessor.unpack() ) {
if (LIBRAW_SUCCESS == RawProcessor.dcraw_process()) {
libraw_processed_image_t* output = RawProcessor.dcraw_make_mem_image();
if (LIBRAW_IMAGE_JPEG == output->type ) {
image.loadFromData((uchar*)output->data,
output->data_size,
"JPEG");
LibRawImagePerformFlip(RawProcessor.imgdata.sizes.flip, image);
} else if (LIBRAW_IMAGE_BITMAP == output->type) {
image= LibRawImageToQImage(
(uchar*)output->data,
output->width,
output->height,
output->colors,
output->bits);
} // else: could not read
LibRaw::dcraw_clear_mem(output);
}
RawProcessor.recycle();
}
}
使用两个辅助函数:
QImage MiscToolsLibRawImageToQImage(const uchar *data,
const int width,
const int height,
const int nCols,
const int colorBits)
{
int colorSize = (colorBits % 8) == 0 ? colorBits / 8 : ceil(colorBits / 8.0);
int numPixels = width * height;
int pixelSize = nCols * colorSize;
uchar* pixels = new uchar[numPixels * 3];
for (int i = 0; i < numPixels; i++, data += pixelSize) {
if (nCols == 3) {
// this ordering produces correct RGB results - don't ask why
// tested with .CR2 (Canon)
pixels[i * 3] = data[3*colorSize];
pixels[i * 3 + 1] = data[colorSize];
pixels[i * 3 + 2] = data[2*colorSize];
} else {
pixels[i * 3] = data[0];
pixels[i * 3 + 1] = data[0];
pixels[i * 3 + 2] = data[0];
}
}
// immediately create a copy since otherwise we'd have to
// 'delete[] pixels' somewhere else, ourselves
// see http://doc.qt.io/qt-5.5/qimage.html#QImage-6
QImage out = QImage(pixels, width, height, width * 3,
QImage::Format_RGB888).copy();
delete[] pixels;
return out;
}
void LibRawImagePerformFlip(const int flip, QImage& image)
{
if (flip != 0) {
QTransform rotation;
int angle = 0;
if (flip == 3) angle = 180;
else if (flip == 5) angle = -90;
else if (flip == 6) angle = 90;
if (angle != 0) {
rotation.rotate(angle);
image = image.transformed(rotation);
}
}
}