Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

In OpenCV multichannel images the columns contain as many sub columns as the number of channels. For example in case of an BGRA color system memory is BGRABGRABGRA... planes are mixed together.

wxImage is a buffer of RGB bytes with an optional buffer for the alpha bytes. So to create a wxImage from external buffer, two buffer are required like *data->RGBRGBRGB and *alpha->AAA

I hope this help... take care of channels order BGR vs RGB

From OpenCV BGRA Mat to wxWidget RGB+A image

void convertMatWithAlphaToWx(const cv::Mat &matBGRA, wxImage &wxRGBA)
{
    CV_Assert(matBGRA.type() == CV_8UC4);
    cv::Mat RGB;
    cvtColor(matBGRA, RGB, CV_BGRA2RGB);
    cv::Mat alpha = cv::Mat::zeros(matBGRA.size(), CV_8UC1);
    int from_to[] = { 3, 0 };
    cv::mixChannels(&matBGRA, 1, &alpha, 1, from_to, 1);
    // !!! Use non static memory because buffers refer to local Mats
    wxRGBA = wx::wxImage(matBGRA.cols, matBGRA.rows, RGB.data, alpha.data, false);
}

From wxWidget RGB+A image to OpenCV BGRA Mat

void convertWxToMatWithAlpha(const wxImage &wxRGBA, cv::Mat &matBGRA)
{
    CV_Assert(wxRGBA.HasAlpha());
    cv::Size sz(wxRGBA.GetWidth(), wxRGBA.GetHeight());
    unsigned char *wxData = wxRGBA.GetData();  //an array of characters in RGBRGBRGB
    unsigned char *wxAlpha = wxRGBA.GetAlpha();

    cv::Mat alpha(sz, CV_8UC1, wxAlpha);  //create a Mat over the wx alpha buf
    cv::Mat RGB(sz, CV_8UC3, wxData);     //create a RGB Mat over the wx data buf
    matBGRA = cv::Mat::zeros(sz, CV_8UC4);  //prepare a BGRA Mat
    // mix input channels to create RGB+Alpha > BGRA 
    cv::Mat in[] = { RGB, alpha };
    //  rgb[0] -> bgra[2] , rgb[1] -> bgra[1] ,
    //  rgb[2] -> bgra[0] , alpha[0]-> bgra[3]
    int from_to[] = { 0, 2, 1, 1, 2, 0, 3, 3 };
    cv::mixChannels(in, 2, &matBGRA, 1, from_to, 4);
    // (i) matBGRA will have its own memory
}

In OpenCV multichannel images the columns contain as many sub columns as the number of channels. For example in case of an BGRA color system system, memory is BGRABGRABGRA... planes are mixed together.

wxImage is uses a buffer of RGB bytes with an optional buffer for the alpha bytes. So to create a wxImage from external buffer, two buffer buffers are required like *data->RGBRGBRGB and *alpha->AAA

below is the code, I hope this help... it helps... take care of channels order BGR vs RGB

From OpenCV BGRA Mat to wxWidget RGB+A image

void convertMatWithAlphaToWx(const cv::Mat &matBGRA, wxImage &wxRGBA)
{
    CV_Assert(matBGRA.type() == CV_8UC4);
    cv::Mat RGB;
    cvtColor(matBGRA, RGB, CV_BGRA2RGB);
    cv::Mat alpha = cv::Mat::zeros(matBGRA.size(), CV_8UC1);
    int from_to[] = { 3, 0 };
    cv::mixChannels(&matBGRA, 1, &alpha, 1, from_to, 1);
    // !!! Use non static memory because buffers refer to local Mats
    wxRGBA = wx::wxImage(matBGRA.cols, matBGRA.rows, RGB.data, alpha.data, false);
}

From wxWidget RGB+A image to OpenCV BGRA Mat

void convertWxToMatWithAlpha(const wxImage &wxRGBA, cv::Mat &matBGRA)
{
    CV_Assert(wxRGBA.HasAlpha());
    cv::Size sz(wxRGBA.GetWidth(), wxRGBA.GetHeight());
    unsigned char *wxData = wxRGBA.GetData();  //an array of characters in RGBRGBRGB
    unsigned char *wxAlpha = wxRGBA.GetAlpha();

    cv::Mat alpha(sz, CV_8UC1, wxAlpha);  //create a Mat over the wx alpha buf
    cv::Mat RGB(sz, CV_8UC3, wxData);     //create a RGB Mat over the wx data buf
    matBGRA = cv::Mat::zeros(sz, CV_8UC4);  //prepare a BGRA Mat
    // mix input channels RGB+Alpha to create RGB+Alpha > BGRA 
    cv::Mat in[] = { RGB, alpha };
    //  rgb[0] -> bgra[2] , rgb[1] -> bgra[1] ,
    //  rgb[2] -> bgra[0] , alpha[0]-> bgra[3]
    int from_to[] = { 0, 2, 1, 1, 2, 0, 3, 3 };
    cv::mixChannels(in, 2, &matBGRA, 1, from_to, 4);
    // (i) matBGRA will have its own memory
}