《学习Opencv》第五章 习题6

时间:2023-11-24 21:43:50

这是第五章 习题5、6的结合版,其中实现了摄像头抓拍功能,能够成功运行。

#include "stdafx.h"
#include "cv.h"
#include "highgui.h" void* getImage()
{
CvCapture* capture=cvCreateCameraCapture(0);
IplImage *img1=NULL,*img2=NULL,*img3=NULL,*frame=NULL,*ppImage=NULL;
char keycode;
cvNamedWindow("frame");
if(capture!=NULL)
{
frame=cvQueryFrame(capture); //注意任何视频(包括摄像头获取的视频的第一帧都是空帧,要从下一帧开始才是图像)
while(1)
{
frame=cvQueryFrame(capture);
cvShowImage("frame",frame);
keycode=cvWaitKey(30); if(keycode==27)
break;
//保存第一张想要保存的图像
if(keycode=='1')
{
img1=cvCreateImage(cvGetSize(frame),frame->depth,1); //将通道数为1对应灰度图像,再将frame利用cvConvertImage转换成灰度图像
cvConvertImage(frame,img1); //也可以利用cvCvtColor(frmae,img1,CV_BGR2GRAY)转成灰度图像
cvSaveImage("C:/Users/shark/Desktop/1.jpg",img1);
}
//保存第二张想要的图像:相对于第一张图像多出一个水杯之类的东西
if(keycode=='2')
{
img2=cvCreateImage(cvGetSize(frame),frame->depth,1);
cvConvertImage(frame,img2);
cvSaveImage("C:/Users/shark/Desktop/2.jpg",img2);
}
}
}
img3=cvCreateImage(cvGetSize(frame),frame->depth,1);
ppImage=cvCreateImage(cvGetSize(frame),frame->depth,1);
//差的绝对值、二值化阈值、开操作
cvAbsDiff(img1,img2,img3);
cvThreshold(img3,img1,20,255,CV_THRESH_BINARY);
cvMorphologyEx(img1,img3,NULL,NULL,CV_MOP_OPEN);
cvCopy(img3,ppImage);
cvSaveImage("C:/Users/shark/Desktop/3.jpg",ppImage);
cvReleaseImage(&img1);
cvReleaseImage(&img2);
cvReleaseImage(&img3);
cvReleaseCapture(&capture);
cvDestroyAllWindows(); return ppImage;
} bool findImage(IplImage* pImage,char nVal, CvPoint* pPos)
{
char* ptr=NULL;
if(pImage->nChannels==1)
{
ptr=pImage->imageData;
if(ptr!=NULL)
{
for(int row=0;row<pImage->height;row++)
{
for(int col=0;col<pImage->width;col++)
{
if(ptr[col]==nVal) //此处图像颜色类型为uchar
{
pPos->x=col;
pPos->y=row;
return true;
}
if(ptr[col]>150) //???
{
int x=0;
}
}
ptr+=pImage->widthStep;
}
}
}
return false;
} int main()
{
IplImage* pImg=NULL;
CvPoint oldPoint={0,0},curPoint={0,0};
int nArea=0,newArea=0;
CvConnectedComp comp;
char* szMyWin="my win"; pImg=(IplImage*)getImage();
if(pImg!=NULL)
{
do
{
if(findImage(pImg,255,&curPoint)) //找像素值为255的像素点
{
cvFloodFill(pImg,curPoint,cvScalar(100),cvScalar(0),cvScalar(0),&comp,8|CV_FLOODFILL_FIXED_RANGE);
if(comp.area<nArea)
{
if(comp.area>0)
cvFloodFill(pImg,curPoint,cvScalar(0),cvScalar(0),cvScalar(0),&comp,8|CV_FLOODFILL_FIXED_RANGE);
}
else
{
newArea=comp.area;
if(nArea>0) //此为对之前区域填充
cvFloodFill(pImg,oldPoint,cvScalar(0),cvScalar(0),cvScalar(0),&comp,8|CV_FLOODFILL_FIXED_RANGE);
memcpy(&oldPoint,&curPoint,sizeof(CvPoint));
//oldPoint=curPoint;
nArea=newArea;
}
}
else
{
cvFloodFill(pImg,oldPoint,cvScalar(255),cvScalar(0),cvScalar(0),&comp,8|CV_FLOODFILL_FIXED_RANGE); //填充最后的最大区域
break;
}
}while(true);
cvSaveImage("C:/Users/shark/Desktop/4.jpg",pImg);
cvNamedWindow(szMyWin);
cvShowImage(szMyWin,pImg);
cvWaitKey(0); cvReleaseImage(&pImg);
cvDestroyWindow(szMyWin);
}
}