threadに基づいて、画像を保存せずにQMLでカメラから処理する方法はありますか?保存せずに画像をキャプチャする
docの例から始めて、capture()関数は画像をPicturesの場所に保存します。 私が達成したいのは、onImageCapturedを使用して毎秒カメラ画像を処理することですが、ドライブに保存したくありません。
私はonImageSavedシグナルを使用してクリーンアップ操作を実装しようとしましたが、onImageCapturedにも影響しています。
threadに基づいて、画像を保存せずにQMLでカメラから処理する方法はありますか?保存せずに画像をキャプチャする
docの例から始めて、capture()関数は画像をPicturesの場所に保存します。 私が達成したいのは、onImageCapturedを使用して毎秒カメラ画像を処理することですが、ドライブに保存したくありません。
私はonImageSavedシグナルを使用してクリーンアップ操作を実装しようとしましたが、onImageCapturedにも影響しています。
this answerで説明したように、mediaObject
でC++とQMLをブリッジすることができます。これはobjectName
(リンクされた回答のように)または専用のQ_PROPERTY
(これについては後で詳しく説明します)を使用して行うことができます。あなたがカメラにフックを持ったら、
QObject * source // QML camera pointer obtained as described above
QObject * cameraRef = qvariant_cast<QMediaObject*>(source->property("mediaObject"));
videoFrameProbed
を接続すなわち
QVideoProbe *probe = new QVideoProbe;
probe->setSource(cameraRef);
、QVideoProbe
オブジェクトのためのソースとして使用します。どちらの場合も、あなたは、このようなコードで終わる必要があります適切なスロットへの信号、すなわち
connect(probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
、それはそれだ:あなたは今processFrame
関数内で自分のフレームを処理することができます。このような関数の実装は、次のようになります。ここ
void YourClass::processFrame(QVideoFrame frame)
{
QVideoFrame cFrame(frame);
cFrame.map(QAbstractVideoBuffer::ReadOnly);
int w {cFrame.width()};
int h {cFrame.height()};
QImage::Format f;
if((f = QVideoFrame::imageFormatFromPixelFormat(cFrame.pixelFormat())) == QImage::Format_Invalid)
{
QImage image(cFrame.size(), QImage::Format_ARGB32);
// NV21toARGB32 convertion!!
//
// DECODING HAPPENS HERE on "image"
}
else
{
QImage image(cFrame.bits(), w, h, f);
//
// DECODING HAPPENS HERE on "image"
}
cFrame.unmap();
}
二つの重要な実装の詳細:
QImage
によって現在サポートされていませんし、手によって変換されるべきYUV formatを使用しています。ここではすべての無効なフォーマットがYUVであるという強い前提を設定しました。それは現在のOS上でifdef
の条件を介して管理する方が良いでしょう。QImage
の一部のみを取ることで、パフォーマンスを大幅に向上させることができます。私はmediaObject
をフェッチするために、すべてのobjectName
アプローチで避けるだろうし、代わりに私がregister a new typeようQ_PROPERTY
アプローチを使用することができますそのことについては。 setSource
は単純です
class FrameAnalyzer
{
Q_OBJECT
Q_PROPERTY(QObject* source READ source WRITE setSource)
QObject *m_source; // added for the sake of READ function
QVideoProbe probe;
// ...
public slots:
void processFrame(QVideoFrame frame);
}
:
bool FrameAnalyzer::setSource(QObject *source)
{
m_source = source;
return probe.setSource(qvariant_cast<QMediaObject*>(source->property("mediaObject")));
}
いつものように登録されると、すなわち、私はこの線に沿って何かを考えています
// other imports
import FrameAnalyzer 1.0
Item {
Camera {
id: camera
// camera stuff here
Component.onCompleted: analyzer.source = camera
}
FrameAnalyzer {
id: analyzer
}
}
このアプローチの大きな利点はreadibilityとCamera
コード及び処理コードとの間のより良好なカップリングである:次のように直接QMLでsource
プロパティを設定することができ
qmlRegisterType<FrameAnalyzer>("FrameAnalyzer", 1, 0, "FrameAnalyzer");
それは(わずかに)より高い実装努力を犠牲にして来る。
本当にあなたがしたいことに依存します。フレーム(タグ/ Qrコードの検索など)だけを処理したい場合は、[mediaObject](http://doc.qt.io/qt-5/qml-qtmultimedia-camera.html#mediaObject-prop ) 以上です。リアルタイムのフィルタリングとオーバーレイを行いたい場合、より多くの作業が必要になります。 2番目のシナリオの詳細については、[この回答](http://stackoverflow.com/a/33238150/2538363)の冒頭にあるリンクを参照してください。 – BaCaRoZzo
私が達成したいのは、QRコードをスキャンすることです。 [this](https://bugreports.qt.io/browse/QTBUG-53083)のためgrabWindow()を使用することができないので、毎秒カメラの出力をキャプチャして画像を処理したいと思います。 – ABCplus
したがって、私はmediaObjectを使用することの提案に基づいて、QCameraオブジェクトへの参照を取得したら、次に何をする必要がありますか? – ABCplus