最近在研究一些基于openCV的目标检测算法,由浅入深,今天是第一天。

首先网上下载了一份较简单的来对视频中运动物体进行二值显示的代码进行学习,以下是我的理解,初学者会犯一些错希望大家予以指正。

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

int
main(int argc,unsigned char* argv[]) {
  
CvCapture* capture = cvCreateFileCapture("out.avi"); IplImage* frame1=NULL; IplImage* frame2=NULL; while(1) {      //通过cvQueryFrame函数获取视频的下一帧,抓取后,capture就指向下一帧,这里抓取的frame不可被释放或修改 frame1 = cvQueryFrame(capture); if(!frame1) { break; }
IplImage* gray1 = cvCreateImage(cvGetSize(frame1), IPL_DEPTH_8U, 1);
  
     //将frame1的彩色图像转化为gray的灰度图像 cvCvtColor(frame1,gray1,CV_BGR2GRAY); frame2
= cvQueryFrame(capture); if(!frame2) { break; } IplImage* gray2 = cvCreateImage(cvGetSize(frame2), IPL_DEPTH_8U, 1); cvCvtColor(frame2,gray2,CV_BGR2GRAY);
IplImage
* gray_diff = cvCreateImage(cvGetSize(gray2), IPL_DEPTH_8U, 1);

     //frame1和frame2分别为视频的相邻两帧,则gray1和gray2分别为相邻帧对应的灰度图像
     //cvAbsDiff函数通过比较gray1和gray2的不同,将两图的不同点找出来,赋给gray_diff cvAbsDiff(gray1,gray2,gray_diff);
for ( int i = 0; i < gray_diff->height; ++i ) {
      //遍历整个gray_diff图像,其imageData成员是该图像的首地址,widthStep是一行占的字节数
      //则这里就是指向了该图像的第i行 uchar
* pucPixel = (uchar*)gray_diff->imageData + i*gray_diff->widthStep; for ( int j = 0; j < gray_diff->width; ++j ) {
       //如果该点的灰度值<35,就置为黑色,表示未变化部分,否则置255,说明运动了
if(pucPixel[j]>35) pucPixel[j]=255; else pucPixel[j]=0; } } IplImage *gray_diff_erode = cvCreateImage(cvGetSize(gray_diff), 8, 1); IplImage *gray_diff_dilate = cvCreateImage(cvGetSize(gray_diff), 8, 1);
    //一个膨胀处理,用gray_diff_dilate存储,一个腐蚀处理,用gray_diff_erode存储
    //其实这里还是不是很理解为什么这两个要成对出现,我将其中一个注释也能显示
    //特别是这里只膨胀以后,即将相似的背景点合并后的图像更更明显
    //后面的1是膨胀或腐蚀的次数,次数越多就越明显 cvDilate(gray_diff,gray_diff_dilate, NULL,
1); //膨胀 cvErode(gray_diff_dilate,gray_diff_erode, NULL,1); //腐蚀 cvNamedWindow("avi"); cvNamedWindow("222"); /*显示视频帧*/ cvShowImage("avi",frame1); cvShowImage("222",gray_diff_erode); char c = cvWaitKey(60); /*退出循环*/ if(c == 27) { break; } cvReleaseImage(&gray1); cvReleaseImage(&gray2); cvReleaseImage(&gray_diff); cvReleaseImage(&gray_diff_erode); cvReleaseImage(&gray_diff_dilate); } cvReleaseCapture(&capture); /*注销窗口,释放图像副本*/ cvDestroyWindow("avi"); cvDestroyWindow("act"); return 0; }