opencv运用帧差法对运动物体检测
程序员文章站
2022-05-30 11:58:50
...
运用帧差法对运动物体检测:
定义一个阈值,下面还会建立一个灰度直方图:
int detectThreshold = 19;
当环境变化时,直方图会产生变化,而这个阈值就是对变化的敏感性
当阈值小时,变化一点就能检测出来,阈值大了,变化一点是检测不出运动物体的
定义获取的图片大小:
cvSetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_WIDTH, 640);
cvSetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_HEIGHT, 480);
可以自己尝试改一下数值看看效果
定义亮度以及对比度:
cvSetCaptureProperty(pCapture, CV_CAP_PROP_BRIGHTNESS, 70);
cvSetCaptureProperty(pCapture, CV_CAP_PROP_CONTRAST, 50);
后面的数值需要自己调至合适
下面是代码
#include "cv.h"
#include "highgui.h"
int main(int argc, char** argv) {
int detectThreshold = 19;
/*初始化相机 */
CvCapture* pCapture = cvCreateCameraCapture(1);
cvSetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_WIDTH, 640);
cvSetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_HEIGHT, 480);
cvSetCaptureProperty(pCapture, CV_CAP_PROP_BRIGHTNESS, 70);
cvSetCaptureProperty(pCapture, CV_CAP_PROP_CONTRAST, 50);
if (NULL == pCapture) {
fprintf(stderr, "Can't initialize webcam!\n");
return 1;
}
IplImage *pFrameA = cvQueryFrame(pCapture);
IplImage *pFrameB = cvCreateImage(cvSize(pFrameA->width, pFrameA->height), pFrameA->depth, pFrameA->nChannels);
IplImage *pFrameDiff = cvCloneImage(pFrameB);
int nDims = 256;
float hRangesArr[] = { 0, 255 };
float* hRanges = hRangesArr;
IplImage *pGrayscaleImage = NULL;
CvHistogram *pHist = cvCreateHist(1, &nDims, CV_HIST_ARRAY, &hRanges, 1);
float fMaxValue = 0.0;
time_t ts = 0; // used to record current timestamp & prevent triggering the monition detection for multi times in 1 second
while (true) {
pFrameA = cvQueryFrame(pCapture);
if (!pFrameA) {
fprintf(stdout, "Can't grab images!\n");
break;
}
cvAbsDiff(pFrameB, pFrameA, pFrameDiff); //找出两张图片的不同s
cvCopy(pFrameA, pFrameB); // 复制图片
pGrayscaleImage = cvCreateImage(cvGetSize(pFrameDiff), IPL_DEPTH_8U, 1);
cvCvtColor(pFrameDiff, pGrayscaleImage, CV_BGR2GRAY);
cvCalcHist(&pGrayscaleImage, pHist, 0, 0);
fMaxValue = 0.0;
cvGetMinMaxHistValue(pHist, 0, &fMaxValue, 0, 0);
cvConvertScale(pHist->bins, pHist->bins, (fMaxValue ? (255.0 / fMaxValue) : 0.0), 0);
double dRealtimeVal = cvGetReal1D(pHist->bins, 10);
if (dRealtimeVal > detectThreshold) { // triggered
time_t currentTimestamp = time(NULL);
if (currentTimestamp - ts >= 1) {
ts = currentTimestamp;
printf("Motion detected @ %s", ctime(¤tTimestamp));
}
}
cvReleaseImage(&pGrayscaleImage); // 释放缓存
pGrayscaleImage = NULL;
cvWaitKey(10); // 等待10ms
}
cvReleaseCapture(&pCapture); // 释放资源
cvReleaseHist(&pHist);
cvReleaseImage(&pFrameA);
cvReleaseImage(&pFrameB);
cvReleaseImage(&pFrameDiff);
pCapture = NULL;
pHist = NULL;
pFrameA = NULL;
pFrameB = NULL;
pFrameDiff = NULL;
return 0;
}
效果图: