1

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

私は今、公式に立ち往生しています。ドキュメントの解読に問題があります:

QImage に格納されている各ピクセルは整数で表されます。整数のサイズは、フォーマットによって異なります。QImage は Format 列挙型で記述されたいくつかの画像フォーマットをサポートしています。

モノクロ イメージは、1 ビット インデックスを使用して、最大 2 色のカラー テーブルに格納されます。モノクロ イメージには、ビッグ エンディアン (MSB ファースト) またはリトル エンディアン (LSB ファースト) の 2 種類があります。

...

createAlphaMask() 関数は、このイメージのアルファ バッファから 1 bpp マスクを作成して返します...

また:

QImage::Format_MonoLSB --- 2 --- 画像は 1 ビット/ピクセルを使用して保存されます。バイトは最下位ビット (LSB) から順にパックされます。

これをcv::Matに転送する方法を明確にするのを手伝ってくれる人はいますか。

また、これを読むことになっているのは、各ピクセルがunsigned char1 ビットになるか、8 ピクセルをビットに格納するかということです。

4

1 に答える 1

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
            }
        }
     }
 }
于 2012-12-07T18:26:33.660 に答える