【问题标题】:Convert 32bit rgb image to 8 bit rgb C++将 32 位 rgb 图像转换为 8 位 rgb C++
【发布时间】:2016-05-13 10:43:58
【问题描述】:

我想将 w x h 的 uint32_t 图像数据转换为 uint8_t 图像。我应该如何转换图像。我想将 leptonica 的 PIX 转换为 opencv Mat。

我想知道使用按位运算符的难点。像素被打包为 AARRGGBB。

我也想转换

cv:Mat 8UC1 到 PIX。 即 8 位单通道图像到 32 位图像。或者,如果您能想到任何其他方法来进行排序。

【问题讨论】:

  • 32bit AARRGGBB 反之亦然
  • 通常 8 位图像使用 256 色调色板。对于每种颜色的固定位数,它太有限了。
  • 是的,我知道。因此,如果您能解释我应该如何将 cv::Mat CV_8UC1 转换为 PIX 数据类型。

标签: opencv leptonica


【解决方案1】:

如果您想用您的数据获得 4 通道 RGBA 图像,您可以尝试将每个 uint32_t 转换为 4 个无符号字符数。有关如何执行此操作的讨论,请参阅 Converting an int into a 4 byte char array (C)。 完成此操作后,您只需使用您获得的数据创建一个 CV_8UC4 类型的新 cv::Mat

【讨论】:

    【解决方案2】:
    uint32_t * imData = yourImageDataPointer;
    uchar * reinterpretedData = (uchar*)imData;
    
    cv::Mat cvImage = cv::Mat(h,w, CV_8UC4);
    
    cv::Mat bgr; // displayable image without alpha channel
    
    cv::cvtColor(cvImage, bgr, CV_RGBA2BGR);
    
    cv::imshow("img", bgr);
    cv::waitKey (0);
    

    如果不符合您的预期,请尝试并发布结果图片

    【讨论】:

    • 谢谢,知道了。但像素的包装是 AARRGGBB。我现在整理好了。
    【解决方案3】:

    这是将 cv::Mat 转换为 leptonicas 32 位 PIX 格式的答案:

    PIX* toPIX(const cv::Mat& img)
    {
        if(img.empty())
            throw std::invalid_argument("Image is empty");
    
        //PIX has got 4 channels hence we need to add one
        //more channel to this image
        cv::Mat alphaImage;
        if(img.type() == CV_8UC3) {
            cv::cvtColor(img,alphaImage,cv::COLOR_BGR2RGBA);
        } else if(img.type() == CV_8UC1) {
            cv::Mat gray = img.clone();
            std::vector<cv::Mat> channelsPlusAlpha;
    
            //construct 4 channel by reapeating gray across 3 channels and filling alpha with constant value
            channelsPlusAlpha.push_back(gray);//channels[2]);//R
            channelsPlusAlpha.push_back(gray);//channels[1]);//G
            channelsPlusAlpha.push_back(gray);//channels[0]);//B
            channelsPlusAlpha.push_back(cv::Mat(img.size(),CV_8UC1,cv::Scalar::all(255)));//A
            cv::merge(channelsPlusAlpha,alphaImage);
        } else {
            throw std::logic_error("Image type undefined");
        }
    
    
        //Prepare PIX
        int w = alphaImage.cols;
        int h = alphaImage.rows;
        int bpl = alphaImage.step1();//bytes per line
        int bpp = alphaImage.channels();//bytes per pixel
        int top = 0; //x (0,0) or if we want to deal with sub image then those coordinates have to be fed
        int left = 0;//y
        uchar* image_data = alphaImage.data;
    
        //Create PIX
        PIX *pix = pixCreate(w,h,32);
        uint32_t* data = pixGetData(pix);
        int wpl = pixGetWpl(pix);//get the words per line
    
        const uint8_t* imagedata = image_data + top * bpl + left * bpp;
    
        for(int y=0; y < h; ++y) {
            const uint8_t* linedata = imagedata; // linescan
            uint32_t* line = data + y *wpl;
            for(int x =0; x < w; ++x) {
                line[x] =   (linedata[0] << 24) |
                            (linedata[1] << 16) |
                            (linedata[2] << 8)  |
                            linedata[3];
    
                linedata += 4;
            }
            imagedata += bpl;
        }
    
        return pix;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-01
      • 2012-07-17
      • 2019-05-23
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      • 2011-07-17
      • 1970-01-01
      相关资源
      最近更新 更多