34

私はOpenCVを初めて使用し、画像をキャプチャしてファイルに保存しようとしています。参考までにコードを以下に掲載します。

jpgファイルは保存中ですが、黒です。

// Capture the Image from the webcam
CvCapture *pCapturedImage = cvCreateCameraCapture(0);

// Get the frame
IplImage *pSaveImg = cvQueryFrame(pCapturedImage);

// Save the frame into a file
cvSaveImage("test.jpg". ,pSaveImg); // A JPG FILE IS BEING SAVED
                                    // OF 6KB , BUT IT IS BLACK

すべての機能が成功しています。XPとVistaの両方で上記のコードを試しましたが、結果は両方で黒い画像になります。私が見逃しているものを教えてください。

4

15 に答える 15

28

C++ を使用する場合は、 C++ インターフェイスを使用することをお勧めします。

using namespace cv;
// Capture the Image from the webcam
VideoCapture cap(0);

// Get the frame
Mat save_img; cap >> save_img;

if(save_img.empty())
{
  std::cerr << "Something is wrong with the webcam, could not get frame." << std::endl;
}
// Save the frame into a file
imwrite("test.jpg", save_img); // A JPG FILE IS BEING SAVED
于 2012-12-04T17:27:42.180 に答える
5

cvQueryFrame() の最初の呼び出しで空の画像が返されることがあります。試す:

IplImage *pSaveImg = cvQueryFrame(pCapturedImage);
pSaveImg = cvQueryFrame(pCapturedImage);

それでもうまくいかない場合は、キャプチャ デバイスを自動的に選択してみてください。

CvCapture *pCapturedImage = cvCreateCameraCapture(-1);

または、n=1、2、3... の他のキャプチャ デバイスを選択してみてください。

CvCapture *pCapturedImage = cvCreateCameraCapture(n);

PS:また、変数名を見てキャプチャされた画像について誤解があると思います。変数 pCapturedImage は画像ではなく、キャプチャです。キャプチャからいつでも画像を「読み取る」ことができます。

于 2009-05-12T21:22:30.170 に答える
5

SaveImage私の経験では、8 ビットとは異なるビット深度のマトリックスが与えられると、OpenCV は黒いイメージを書き込みます。実際、これは一種の文書化されています。

この関数を使用して保存できるのは、8 ビットのシングル チャネルまたは 3 チャネル ('BGR' チャネル順) の画像のみです。形式、深さ、またはチャネルの順序が異なる場合は、保存する前に と を使用cvCvtScalecvCvtColorて変換するか、universalcvSaveを使用して画像を XML または YAML 形式に保存します。

あなたの場合、最初にキャプチャされた画像の種類を調査し、キャプチャ プロパティを変更するか (CV_CAP_PROP_CONVERT_RGB重要であると思われます)、後で手動で変換することができます。

これは、OpenCV で 8 ビット表現に変換する方法の例です。ccこれはタイプ の元の行列でCV_32FC1cc8u実際には によって書かれたスケーリングされたバージョンですSaveImage:

# I want to save cc here
cc8u = CreateMat(cc.rows, cc.cols, CV_8U)
ccmin,ccmax,minij,maxij = MinMaxLoc(cc)
ccscale, ccshift = 255.0/(ccmax-ccmin), -ccmin
CvtScale(cc, cc8u, ccscale, ccshift)
SaveImage("cc.png", cc8u)

(申し訳ありませんが、これは Python コードですが、C/C++ に簡単に変換できるはずです)

于 2011-02-22T12:25:58.630 に答える
3

これが明白すぎる場合は申し訳ありません。WebカメラがOpenCVによって適切に表示および検出されていることを確認します。つまり、キャプチャされたフレームを「highGui」ウィンドウにリダイレクトしたときに画像が表示されますか?たとえば、次のようになります。

 frame = cvQueryFrame( capture );
 cvNamedWindow( "myWindow", CV_WINDOW_AUTOSIZE );
 cvShowImage( "myWindow", frame );
于 2009-05-13T22:28:10.617 に答える
3

私は問題を知っています!「test.jpg」の後にドットを入れるだけです!

cvSaveImage("test.jpg". ,pSaveImg);

私は間違っているかもしれませんが、それは良くないと思います!

于 2010-04-18T21:50:45.773 に答える
2

Microsoft WebCam でも同様の問題がありました。Matlab の画像取得ツールボックスを調べたところ、サポートされている最大解像度は 640*480 であることがわかりました。

openCVのコードを変更して追加しました

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 352); 
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 288);

次にサポートされている解像度で変更された cvQueryFrame 関数が、画像を保存する前にいくつかの初期フレームをスキップし、最終的に機能するようになる前に。

作業コードを共有しています

#include "cv.h" 
#include "highgui.h" 
#include <stdio.h> 



using namespace cv;
using namespace std;

int main() 
{
CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 352); 
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 288)


 // Get one frame
IplImage* frame;

for (int i = 0; i < 25; i++) 
{
frame = cvQueryFrame( capture );
}


printf( "Image captured \n" );  
//IplImage* RGB_frame = frame;
//cvCvtColor(frame,RGB_frame,CV_YCrCb2BGR);
//cvWaitKey(1000);
cvSaveImage("test.jpg" ,frame);
//cvSaveImage("cam.jpg" ,RGB_frame);

printf( "Image Saved \n" );

//cvWaitKey(10);

// Release the capture device housekeeping
cvReleaseCapture( &capture );
//cvDestroyWindow( "mywindow" );
return 0;
}

私の提案:

  1. 最大解像度でフレームをグラブしない
  2. カメラを正しく初期化するためにいくつかのフレームをスキップします
于 2013-05-05T05:21:40.510 に答える
1

OpenCVの健全性チェックを実行することをお勧めします

opencvのbinディレクトリにある一連の小さな実行可能ファイル。

カメラに問題がないかどうかを確認します

于 2009-07-07T15:42:06.530 に答える
1

Windows Vista でも同じ問題が発生しました。前にcvQueryFrame次のコードを追加しました。

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 720);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
于 2010-08-19T16:21:05.177 に答える
1

セイント・ルイスは正しい。cvCaptureFromCAM でカメラをアクティブにすると、自動ホワイト バランスはまだ調整されていないため (処理が遅くなります)、最初のフレームでほぼ白またはほぼ黒 (カメラと照明条件によって異なります) が表示される場合があります。シーンの稲妻が突然変化した場合も同様です。カメラを開いてからしばらく待ってからバッファをフラッシュすれば準備完了です。

于 2011-06-20T18:51:43.837 に答える
1

古い投稿を持ち出して申し訳ありませんが、このスレッドに出くわした人に別の回答を提供したかった.

私も同じ問題を抱えていました。何をやっても真っ黒にしか見えませんでした。cvQueryFrame を複数回連続して呼び出してみたところ、5 回以上実行すると画像が表示されることに気付きました。そこで、「限界点」がどこにあるかを確認するために、呼び出しを 1 つずつ削除し始めました。私が見つけたのは、各呼び出しを削除するたびに画像が暗くなるということでした. 1回の呼び出しでほぼ真っ黒な画像が表示されましたが、よく見ると自分の画像がわかりました。

私は自分の理論をテストするために 10 回連続して電話をかけてみました。うまくいけば、これはあなたが遭遇したのと同じ問題でした.

イメージングについてはよくわかりませんが、cvQueryFrame を複数回連続して呼び出すと、カメラの露光時間が長くなるようです。これは間違いなく問題を解決しますが、最も洗練された解決策とは思えません。露出を増やすパラメーター、または画像を明るくする他のパラメーターを見つけることができるかどうかを確認します。

幸運を!

于 2011-03-17T23:31:58.893 に答える
0

OSXでは、ビデオフレームと静止画像の保存は、cvSaveImageへのフルパスを指定した場合にのみ機能しました。

cvSaveImage("/Users/nicc/image.jpg",img);
于 2011-04-25T09:15:18.303 に答える
0

私の経験から、使用時にキャプチャされる最初の数フレームは次のとおりです。

frame = cvQueryFrame( capture );

空白になりがちです。しばらく (約 3 秒) 待ってから、画像をキャプチャしてみてください。

于 2009-07-04T07:54:51.777 に答える
0

私は、単にカメラが最初のフレームで初期化されていないと思います。10 フレーム後に画像を保存してみてください。

于 2010-05-15T11:10:54.530 に答える