使用单色QImage

时间:2012-12-06 22:53:08

标签: c++ qt opencv

我正在尝试从QPixmap中提取位掩码并将其传递给OpenCV。我的位掩码是通过“绘画”操作创建的。

到目前为止,我的流程一直是:

  1. 创建QPixmap, QPixmap::fill(QColor(0,0,0,0))并使用QPainterQPainter::setPen(QColor(255,0,0,255))合并QPainter::drawPoint(mouse_event->pos()

  2. 准备好提取位掩码QPixmap::toImage()然后QImage::createAlphaMask(),记录后返回QImage::Format_MonoLSB

  3. 我现在正式陷入困境。我无法破译文档:

      

    存储在QImage中的每个像素由整数表示。整数的大小取决于格式。 QImage支持Format enum描述的几种图像格式。

         

    使用1位索引将单色图像存储到最多两种颜色的颜色表中。有两种不同类型的单色图像:大端(MSB优先)或小端(LSB优先)位顺序。

         

    ...

         

    createAlphaMask()函数构建并返回此图像中alpha缓冲区的1-bpp掩码...

    此外:

      

    QImage :: Format_MonoLSB --- 2 ---图像以每像素1位存储。字节首先用较低有效位(LSB)打包。

    任何人都可以帮我澄清如何将其转换为cv :: Mat。

    另外,我应该读到这个,每个像素都是unsigned char,或者我们将存储8个像素。

1 个答案:

答案 0 :(得分:4)

我成功地将单色QImage传输到了cv :: Mat。我希望以下代码对其他人有用:

重要编辑:此代码存在重大错误。 bytesPerLine在某些计算机上按字节对齐以及字对齐。因此,width()应与cur_byte

一起使用
QImage mask; //Input from wherever
cv::Mat workspace;
if(!mask.isNull() && mask.depth() == 1)
{
    if(mask.width() != workspace.cols || mask.height() != workspace.rows)
        workspace.create(mask.height(), mask.width(), CV_8UC1);

    for(int i = 0; i < mask.height(); ++i)
    {
        unsigned char * cur_row = mask.scanLine(i);
        //for(int cur_byte = 0, j = 0; cur_byte < mask.bytesPerLine(); ++cur_byte) wrong
        for(int cur_byte = 0, j = 0; j < mask.width(); ++cur_byte)
        {
            unsigned char pixels = cur_row[cur_byte];
            for(int cur_bit = 0; cur_bit < 8; ++cur_bit, ++j)
            {
                if(pixels & 0x01) //Least Significant Bit
                    workspace.at<unsigned char>(i, j) = 0xff;
                else
                    workspace.at<unsigned char>(i, j) = 0x00;
                 pixels = pixels >> 1; //Least Significant Bit
            }
        }
     }
 }