2016-05-13 130 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; 
}