差分フレームの白の箇所(動いた場所)の画素数をカウントするプログラムを作成しております。
カメラを手で覆った場合や、動いてない場合にはカウントが上がらないようにしたいのですが上手くいきません。
原因などご教授お願いいたします。
//カメラ入力から3フレームを取り出し、差分を計算する。
//変数:thの値を基準として閾値処理(threshold)を行い、変化した部分を白色で描画する。
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
//閾値(threshold)の設定
static const int th = 127;
int main(void)
{
int cout;
//カメラを開く
cv::VideoCapture cap(0);
int a, b;
int GunRGB;
int flag = 0;
int widthcount = 0;
int resultDATA = 0;
//カメラが開けたか確認
if (!cap.isOpened()) return -1;
//変数の準備
cv::Mat im1, im2, im3, frame;
cv::Mat d1, d2, diff;
cv::Mat im_mask, mask;
//ウィンドウを2枚生成
cv::namedWindow("in");
cv::namedWindow("out");
//カメラから3フレーム取り出す
cap >> frame;
cv::cvtColor(frame, im1, CV_RGB2GRAY);
cap >> frame;
cv::cvtColor(frame, im2, CV_RGB2GRAY);
cap >> frame;
cv::cvtColor(frame, im3, CV_RGB2GRAY);
while (1)
{
//差分1:フレーム1と2の差を求める
cv::absdiff(im1, im2, d1);
//差分2:フレーム2と3の差を求める
cv::absdiff(im2, im3, d2);
//差分1と差分2の結果を比較(論理積)し、diffに出力
cv::bitwise_and(d1, d2, diff);
//差分diffのうち、閾値thを超えている部分を1、それ以外を0としてmaskに出力
cv::threshold(diff, mask, 5, 1, cv::THRESH_BINARY);
//マスクmaskのうち、1(True)の部分を白(0)に、0(False)の部分を黒(255)にしてim_maskに出力
cv::threshold(mask, im_mask, 0, 255, cv::THRESH_BINARY);
//メディアンフィルタを使った平滑化によってゴマ塩ノイズを除去、アパーチャサイズ5
//cv::medianBlur(im_mask, im_mask, 5);
//ウィンドウ2枚にそれぞれ入力画像、差分画像を表示
cv::imshow("in", frame);
cv::imshow("out", im_mask);
int width = im_mask.cols;
int height = im_mask.rows;
// int channels = im_mask.channels();
int channels = 1;
for (int j = 0; j<height; j++)
{
int step = j* width;
for (int i = 0; i<width; i++)
{
int elm = i*im_mask.elemSize();
for (int c = 0; c < channels; c++)
{//flag は0が黒,1が白 im_mask.dataは0が白,255が黒
if (flag == 0){
if (im_mask.data[step + elm + c] == 0){
flag = 1;
widthcount = widthcount + 1;
GunRGB = +1;
}
}
else if (flag == 1)
if (im_mask.data[step + elm + c] == 255){
widthcount = 0;
flag = 0;
}
else if (im_mask.data[step + elm + c] == 0)
{
widthcount = widthcount + 1;
}
}
if (j == height - 1 && i == width - 1){
//フレームが終了時に初期化
resultDATA = resultDATA + (widthcount-1 / GunRGB-1);
widthcount = 1;
GunRGB = 1;
flag = 0;
}
}
}
printf("ピクセルカウント数:%d\n",resultDATA);
//新しいフレームをカメラから一つ取り出し、3つのフレームを全てずらす
im2.copyTo(im1, im2);
im3.copyTo(im2, im3);
cap >> frame;
cv::cvtColor(frame, im3, CV_RGB2GRAY);
//ウィンドウ上でEscキーが押されたらプログラム終了
if (cv::waitKey(27) >= 0)
{
cv::destroyAllWindows();
break;
}
}
}