0

IplImage IPL_DEPTH_32S を QImage Format_RGB32 に変換する最速の方法は何ですか?

カムから写真をキャッチし、1 秒あたり 30 フレームの頻度でフォームに表示する必要があります。QImage コンストラクターを使用しようとしました:

QImage qImage((uchar *) image->imageData, image->width, image->height, QImage::Format_RGB32);

しかし、この後、画像が破損しました。では、どうすればこれを高速に実行できますか (ピクセルごとに QImage を配置するのは適切な決定ではないと思います)。

4

3 に答える 3

3

始める前に、OpenCV はデフォルトで BGR 形式を使用します。RGBではありません!したがって、を作成する前に、次の方法で RGBQImageに変換する必要があります。IplImage

cvtColor(image, image, CV_BGR2RGB);

次に、次のことができます。

QImage qImage((uchar*) image->imageData, image->width, image->height, QImage::Format_RGB32);

上記のコンストラクターは、ドキュメントに記載されているように、考えているようにデータをコピーしないことに注意してください。

バッファは、QImage の存続期間中ずっと有効である必要があります

So if you are having performance issues are not because of the conversion procedure. It is most probably caused by the drawing method you are using (which wasn't shared in the question). To summarize a lot of blah blah blah, you should render the QImage to an OpenGL texture and let the video card do all the drawing for you.

Your question is a bit misleading because your primary objective is not to find the fastest conversion method, but one that actually works since yours don't.

Another important thing to keep in mind, when you said:

image was corrupted after this

これは完全にあいまいであることを知っておく必要があります。この効果には多くの原因があり、ソースコードがなければ、何が間違っているのかを確実に伝えることは不可能であるため、まったく役に立ちません。元の画像と破損した画像を共有すると、問題がどこにあるかの手がかりが得られる場合があります。

それだけです。幸運を。

于 2012-07-07T02:01:58.707 に答える
0

少し前に、インターネットでそれを行う方法の例をいくつか見つけました。より簡単な方法で画像をコピーする方法について、例を少し改善しました。Qt は通常、char ピクセルでのみ動作します (他の画像形式は通常 HDR 画像と呼ばれます)。opencv で 32 ビット rgb のビデオ バッファを取得する方法を知りたいと思っていました...私はそれを見たことがありません!

opencv にカラー画像がある場合は、この関数を使用してメモリを割り当てることができます。

QImage* allocateqtimagefromcv(IplImage* cvimg)
    {
        //if (cvimg->nChannels==1)
        //  {
        //  return new QImage(cvimg->width,cvimg->height,QImage::Format_Indexed8);
        //  }
        if (cvimg)
            {
            return new QImage(cvimg->width,cvimg->height,QImage::Format_ARGB32);
            }
    }

IplImage を qt イメージにコピーするには、簡単な方法で次の関数を使用できます。

void  IplImage2QImage(IplImage *iplImg,QImage* qimg)
{

char *data = iplImg->imageData;
    int channels = iplImg->nChannels;
int h = iplImg->height;
int w = iplImg->width;
for (int y = 0; y < h; y++, data += iplImg->widthStep)
{
for (int x = 0; x < w; x++)
{
char r, g, b, a = 0;
if (channels == 1)
{
r = data[x * channels];
g = data[x * channels];
b = data[x * channels];
}
else if (channels == 3)
{
r = data[x * channels + 2];
g = data[x * channels + 1];
b = data[x * channels];
}

if (channels == 4)
{
a = data[x * channels + 3];
qimg->setPixel(x, y, qRgba(r, g, b, a));
}

}
}


}

次の関数は、より迅速な解決策になる可能性があります。

static QImage IplImage2QImage(const IplImage *iplImage)
{
  int height = iplImage->height;
  int width = iplImage->width;
  if (iplImage->depth == IPL_DEPTH_8U && iplImage->nChannels == 3)
  {
      const uchar *qImageBuffer =(const uchar*)iplImage->imageData;
      QImage img(qImageBuffer, width, height, QImage::Format_RGB888);
      return img.rgbSwapped();
  }else{
    //qWarning() << "Image cannot be converted.";
   return QImage();
  }
} 

私の機能がお役に立てば幸いです。多分誰かがそれを行うより良い方法を知っています:)

于 2012-07-11T15:10:13.847 に答える
0

IPL_DEPTH_32Sは 32 ビット ピクセルのグレースケールです。ピクセルの順序を確認するためにカラー イメージをパックする場合、通常は実際の「イメージ」ではなく深度データに使用されます。

QImage::Format_ARGB32_Premultipliedグラフィックカードが使用するものであるため、最速の QImage 形式です。データ順序は実際には BGRA であり、A チャネルは少なくともピクセルと同じ大きさ (つまり、アルファを使用したくない場合は 255) である必要があることに注意してください。

cv::cvtColor() には RGB2BGRA と BGR2RGBA があります

于 2012-07-07T04:42:12.523 に答える