OpenCVを用いて"s"キーを押したら静止画保存が始まり、再度"s"キーを押したら保存が終了しるプログラムを作成しています。(保存レートは1秒間で30フレームの静止画保存で考えています)また、保存する静止画を指定したフォルダに保存するプログラムを作成していますが、プログラム作成の経験が浅く、なかなかうまく作れず困っております。どのようにプログラムを組めばこのようなプログラムが作れるのでしょうか。下記のプログラムは作成でき、これを基礎にして作り上げていこうと考えています。プログラムの内容としては"c"キーを押した分だけ、連番でbip形式で画像を保存するプログラムです。精度の関係上timegettime関数を使用したいと考えているのですが、、。
<ソースプログラム>
#include <stdio.h>
#include <highgui.h>
int main( int argc, char** argv ){
int key; // キー入力用変数
int counter = 0;
CvCapture *capture; // キャプチャ用構造体
IplImage *frameImage; // キャプチャ画像用IplImage
char str[32];
char windowNameCapture[] = "CMOS Camera Image"; // ウィンドウネーム
// カメラの初期化
if( ( capture = cvCreateCameraCapture(-1)) == NULL ){
// カメラデバイスが検出できない場合
printf("カメラデバイスを検出できません\n");
return -1;
}
// ウィンドウ生成
cvNamedWindow( windowNameCapture, CV_WINDOW_AUTOSIZE );
// メインループ
while(1){
// カメラからの1フレームをframeImageに格納
frameImage = cvQueryFrame( capture );
// 画像表示
cvShowImage( windowNameCapture, frameImage );
// 'ESC'キーが入力されたらループを抜ける
key = cvWaitKey(1);
if( key == '\x1b' ){
break;
// 静止画保存
} else if( key == 'c'){
sprintf_s(str, "cmosview%04d.bmp",counter++);
cvSaveImage(str, frameImage );
}
}
// キャプチャ解放
cvReleaseCapture( &capture );
// ウィンドウ破棄
cvDestroyWindow( windowNameCapture );
return 0;
}
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
こんばんは。
補足いただきました。遅れてしまってすんません。常にカメラデバイスから、映像が上がってくるのだと思います・・・。チョッと勘違いしてしまいました。
今回、コンソールに対してprintfで動きを追っています。
映像が写されながら、Sキーが押された瞬間に録画開始、もう一回押すと録画停止です(カメラデバイスからの映像は映り続ける筈)。
修正を入れましたので以下を参考にされて下さい。
+-----------------------------------------------------------------------
// メインループ
while(1){
/*----------追加プログラム----------*/
// カメラから1フレームをframeImageに格納
frameImage = cvQueryFrame( capture );
printf("フレームの問い合わせ\n");
// 画像表示
cvShowImage( windowNameCapture, frameImage );
printf("フレームの描画中\n");
key = cvWaitKey(1);
// 静止撮影ボタンが押された
if(key =='c')
{
sprintf_s( str, "cmosview%04.bmp", counter++ );
cvSaveImage( str, frameImage );
}
// 録画ボタンが押された
else if(key == 's')
{
// トグルする
bCapture ^=TRUE;
::printf("%s\n", bCapture?"録画開始":"録画停止");
// キャプチャーの開始を命じられたので開始時刻を取得
if(bCapture)
{
dwCurrentTime = dwLastTime = ::timeGetTime();
}
}
// 'ESC'キーが入力されたらループを抜ける
else if(key == '\x1b')
{
printf("終了します\n");
break;
}
//キャプチャーしていないので引き返す
if(!bCapture)
continue;
// 最新時間を取得
dwCurrentTime = ::timeGetTime();
// 経過時間がレートに満たないので引き返す
if(dwCurrentTime - dwLastTime <= 30)
continue;
// 現在のタイムを最新のタイムにする
dwLastTime = dwCurrentTime;
// 保存
sprintf_s( str, "cmosview%4d.bmp", counter++ );
cvSaveImage( str, frameImage );
printf("%s\n", str);
}
-----------------------------------------------------------------------+
No.1
- 回答日時:
こんばんは。
チョッと今カメラデバイスが無いので、実行は出来ない状態ですが、こんな感じで出来ませんか。
timeGetTime()を使用する際にはwinmm.libをリンクするのを忘れないで下さい。
録画開始と同時に再生される事を前提に、ループの部分だけ書きます。参考程度に。
#include<windows.h>
#include<mmsystem.h>
#pragma comment(lib, "winmm.lib")
+-----------------------------------------------------------------------
DWORD dwCurrentTime = 0;
DWORD dwLastTime = ::timeGetTime();
BOOL bCapture = FALSE;
//タイマ精度を1ミリ秒にする
::timeBeginPeriod(1);
// メインループ
while(1)
{
//現在のタイム
dwCurrentTime = ::timeGetTime();
//保存レート30ミリ秒経過しないので引き返す
if(dwCurrentTime - dwLastTime < 30)
continue;
//現在のタイムを最新のタイムにする
dwLastTime = dwCurrentTime;
// 録画中
if(bCapture)
{
// カメラからの1フレームをframeImageに格納
frameImage = cvQueryFrame( capture );
// 画像表示
cvShowImage( windowNameCapture, frameImage );
// 保存
sprintf_s(str, "cmosview%04d.bmp",counter++);
cvSaveImage(str, frameImage );
}
// 'ESC'キーが入力されたらループを抜ける
key = cvWaitKey(1);
if( key == '\x1b' )
{
break;
// 静止画保存
}
else if( key == 'c')
{
sprintf_s(str, "cmosview%04d.bmp",counter++);
cvSaveImage(str, frameImage );
}
// 録画開始/停止
else if( key == 's')
{
// トグルする
bCapture ^= TRUE;
::printf("%s\n", bCapture ? "録画開始" : "録画停止");
}
}
-----------------------------------------------------------------------+
この回答への補足
早速のご連絡有難う御座います。下記のようなプログラムにて実行致しました。エラーもなく、デバッグできましたが、プログラムを起動させると一瞬で終了してしまいました。80行目のcvWaitKeyの変数を0にすると表示されたままですが、カメラからの入力がありません。しかし、非常に勉強になったので引き続き、エラー原因を探って行きたいと思います。お忙しい中、有難う御座います。もし、宜しければ引き続き、ご指導宜しくお願い致します。
----------ソースプログラム----------
#include <stdio.h>
#include <highgui.h>
#include <windows.h> // 追加
#include <mmsystem.h> // 追加
#pragma comment(lib,"winmm.lib") // 追加
int main( int argc, char** argv ){
int key; // キー入力用変数
int counter = 0;
CvCapture *capture; // キャプチャ用構造体
IplImage *frameImage; // キャプチャ画像用IplImage
char str[32];
char windowNameCapture[] = "CMOS Camera Image"; // ウィンドウネーム
DWORD dwCurrentTime = 0; // 追加
DWORD dwLastTime = ::timeGetTime(); // 追加
BOOL bCapture = FALSE; // 追加
// タイマ精度を1msにする
::timeBeginPeriod(1); // 追加
// カメラの初期化
if( ( capture = cvCreateCameraCapture(-1)) == NULL ){
// カメラデバイスが検出できない場合
printf("カメラデバイスを検出できません\n");
return -1;
}
// ウィンドウ生成
cvNamedWindow( windowNameCapture, CV_WINDOW_AUTOSIZE );
// メインループ
while(1){
// カメラからの1フレームをframeImageに格納
// frameImage = cvQueryFrame( capture );
// 画像表示
// cvShowImage( windowNameCapture, frameImage );
// 'ESC'キーが入力されたらループを抜ける
// key = cvWaitKey(1);
// if( key == '\x1b' ){
// break;
// 静止画保存
// } else if( key == 'c'){
// sprintf_s(str, "cmosview%04d.bmp",counter++);
// cvSaveImage(str, frameImage );
// }
/*----------追加プログラム----------*/
// 現在の時間
dwCurrentTime = ::timeGetTime();
// 保存レートの30msを経過しないので引き返す
if( dwCurrentTime - dwLastTime < 30 )
continue;
// 現在のタイムを最新のタイムにする
dwLastTime = dwCurrentTime;
// 録画中
if(bCapture)
{
// カメラから1フレームをframeImageに格納
frameImage = cvQueryFrame( capture );
// 画像表示
cvShowImage( windowNameCapture, frameImage );
// 保存
sprintf_s( str, "cmosview%4d.bmp", counter++ );
cvSaveImage( str, frameImage );
}
// 'ESC'キーが入力されたらループを抜ける
key = cvWaitKey(1);
if ( key = '\x1b' )
{
break;
// 静止画の保存
}
else if( key = 'c' )
{
sprintf_s( str, "cmosview%04.bmp", counter++ );
cvSaveImage( str, frameImage );
}
// 録画の開始/停止
else if ( key = 's' )
{
// トグルする
bCapture ^=TRUE;
::printf("%s\n", bCapture?"録画開始":"録画停止");
}
}
/*----------ここまで----------*/
// キャプチャ解放
cvReleaseCapture( &capture );
// ウィンドウ破棄
cvDestroyWindow( windowNameCapture );
return 0;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C言語 3 2022/11/09 13:27
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# 【C++】IDirect3DSurfaceのディープコピーは可能ですか? 1 2022/07/06 02:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
構文エラー";"が型の前にあり...
-
for文の中にswitch文はいれられ...
-
C言語 数字以外を入力させない...
-
c言語for文
-
#if 1 #elseの意味について
-
c言語で平均をだす
-
n個からm個を取り出すプログ...
-
行列をべき乗させるプログラム
-
scanf関数を用いての加減乗除%...
-
C言語で電卓を作成する。
-
c言語プログラミングで1から100...
-
配列を使って魔方陣
-
C言語 偶数判定
-
配列を関数に渡す方法
-
初心者です。for文、if文を使っ...
-
C言語 重複しない4ケタの乱数...
-
C言語プログラムが理解できなくて…
-
C言語の二分法のプログラムにつ...
-
C言語階乗の総和を求める
-
scanfが実行されません
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構文エラー";"が型の前にあり...
-
#if 1 #elseの意味について
-
for文の中にswitch文はいれられ...
-
C言語階乗の総和を求める
-
配列を使って魔方陣
-
C言語 数字以外を入力させない...
-
C言語プログラムが理解できなくて…
-
配列を関数に渡す方法
-
初心者です。for文、if文を使っ...
-
scanf関数を用いての加減乗除%...
-
c言語プログラミングで1から100...
-
getcの改行判定
-
while文について、c言語...
-
プログラミングで二番目に大き...
-
VHDLで、case文とwhen文のどち...
-
C言語で電卓を作成する。
-
C言語の二分法のプログラムにつ...
-
階乗のプログラム!!
-
プログラミングに関して
-
C言語についてですfor ifをつか...
おすすめ情報