opencv 将Libraw格式转换为cv::Mat

z4iuyo4d  于 2023-03-19  发布在  其他
关注(0)|答案(1)|浏览(197)

我试图加载RAW格式(特别是尼康。NEF)与libraw库,然后将其转换为opencv格式cv::Mat
以前有人解决过这个问题吗?我该怎么做?

tp5buhyn

tp5buhyn1#

我有一个从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);
        }
    }
}

相关问题