2016-05-13 13 views
0

Ich möchte uint32_t Bilddaten von w x h zu uint8_t Bild konvertieren. Wie soll ich das Bild konvertieren? Ich möchte Leptonicas PIX in opencv Mat umwandeln.Konvertieren von 32-Bit-RGB-Bild in 8-Bit-RGB C++

Ich möchte den harten Weg mit den Bitwise-Operatoren wissen wollen. Die Pixel sind als AARRGGBB gepackt.

Auch würde Ich mag

cv konvertieren: Mat 8UC1 zu PIX. , d.h. 8-Bit-Einzelkanalbild zu 32-Bit-Bild. Oder wenn Sie sich eine andere Möglichkeit vorstellen können, dies zu sortieren.

+0

32 rgb oder rgba? – Micka

+0

32bit AARRGGBB auch umgekehrt –

+0

Normalerweise verwenden 8-Bit-Bilder eine Palette von 256 Farben. Mit festen Bits pro Farbe ist es zu begrenzt. – i486

Antwort

1

Wenn Sie ein 4-Kanal-RGBA-Bild mit Ihren Daten erhalten möchten, können Sie versuchen, jedes Ihrer uint32_t in 4 vorzeichenlose Char-Zahlen umzuwandeln. Eine Diskussion dazu finden Sie unter Converting an int into a 4 byte char array (C). Sobald dies geschehen ist, müssen Sie nur einen neuen cv::Mat vom Typ CV_8UC4 mit den Daten, die Sie erhalten haben, erstellen.

+0

Ich möchte den gehörten Weg lernen. –

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

bitte versuchen Sie dies und das Ergebnisbild hinterlassen, wenn sie nicht das, was erwartet Sie

+0

Danke, verstanden. aber das Packen der Pixel ist AARRGGBB. Ich habe es jetzt sortiert. –

1

Hier ist die Antwort ist, die cv :: Mat konvertieren leptonicas Format 32bit PIX: bit

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; 
}