2016-05-13 390 views
0

我想将wx h的uint32_t图像数据转换为uint8_t图像。我应该如何转换图像。我想将leptonica的PIX转换为opencv Mat。转换32位rgb图像为8位rgb C++

我想知道使用位运算符的困难方式。像素被打包成AARRGGBB。

此外,我想转换

CV:垫8UC1到PIX。 即8位单通道图像到32位图像。或者,如果你能想出任何其他方式来进行排序。

+0

32位rgb或rgba? – Micka

+0

32位AARRGGBB也反之亦然 –

+0

一般8位图像使用256色的调色板。由于每种颜色的固定位数太有限。 – i486

回答

1

如果你想获得与您的数据的4通道RGBA图像,你可以尝试每个uint32_t的的转换为4张无符号的字符数。有关如何执行此操作的讨论,请参见Converting an int into a 4 byte char array (C)。 一旦做到这一点,你只需要创建一个你所获得的数据类型CV_8UC4的新cv::Mat

+0

我想了解听到的方式。 –

1
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); 

请尝试这一点,并发布结果图像,如果它不是你所期望的

+0

谢谢,明白了。但像素的包装是AARRGGBB。我现在把它整理好了。 –

1

下面是简历::垫转换为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; 
}