/**********************************************************************
imageZooming
Release Date: 2011/01/11
Copyright (C) 2011 Zhijie Lee
email: onezeros.lee@gmail.com
web: http://blog.csdn.net/onezeros
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**********************************************************************/
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#pragma comment(lib,"cv210d.lib")
#pragma comment(lib,"cxcore210d.lib")
#pragma comment(lib,"highgui210d.lib")
#include <iostream>
#include <queue>
using namespace std;
class CvTarget{
public:
int erea;//size
int top;//position
int bottom;
int left;
int right;
CvTarget():erea(0),top(0),bottom(0),left(0),right(0){}
CvPoint getCenter(){return cvPoint((right+left)>>1,(bottom+top)>>1);}
int getWidth(){return right-left;}
int getHeight(){return bottom-top;}
};
void cvFindTarget(const IplImage* img,CvTarget& targets);
static const int HandEreaThreshold=500;
int main(int argc,char** argv)
{
CvCapture* capture=cvCreateCameraCapture(-1);
if (!capture){
cout<<"failed to open camera"<<endl;
exit(0);
}
//image for show
IplImage* img=cvLoadImage("Song.jpg");
if (!img){
cout<<"failed to load image"<<endl;
exit(0);
}
CvSize showSize=cvGetSize(img);
//processing window size
const CvSize winSizeProcess=cvSize(320,240);
IplImage* imgColor=cvCreateImage(winSizeProcess,8,3);
IplImage* imgGray=cvCreateImage(winSizeProcess,8,1);
int threshold=140;
cvNamedWindow("processing");
cvMoveWindow("processing",0,0);
cvCreateTrackbar("threshold","processing",&threshold,200,NULL);
int oldImgErea=-1;
bool isZooming=false;
IplImage* imgHand;
while (imgHand=cvQueryFrame(capture)){
cvResize(imgHand,imgColor);
cvCvtColor(imgColor,imgColor,CV_RGB2YCrCb);
cvSplit(imgColor,NULL,NULL,imgGray,NULL);
cvThreshold(imgGray,imgGray,threshold,255,CV_THRESH_BINARY);
cvShowImage("processing",imgGray);
if (isZooming){
cvErode(imgGray,imgGray);
cvDilate(imgGray,imgGray);
CvTarget target;
cvFindTarget(imgGray,target);
if (target.erea>HandEreaThreshold){
float scale=1.0f;
if (oldImgErea>0){
scale=(float)target.erea/oldImgErea;
}
oldImgErea=target.erea;
showSize.width*=scale;
showSize.height*=scale;
//in defense of limit extreme situation
if (showSize.width<4||showSize.height<4||
showSize.width>2000||showSize.width>2000){
showSize=cvGetSize(img);
}
}
}
IplImage* imgResized=cvCreateImage(showSize,8,3);
cvResize(img,imgResized);
static int screenWidth=1024;
static int screenHeight=768;
cvMoveWindow("image",(screenWidth-showSize.width)>>1,(screenHeight-showSize.height)>>1);
cvShowImage("image",imgResized);
cvReleaseImage(&imgResized);
int keyPressed=cvWaitKey(3);
if(keyPressed==27){
break;
}else if (keyPressed==' '){//start/strop zooming
isZooming=!isZooming;
}
}
cvReleaseImage(&img);
cvReleaseCapture(&capture);
return 0;
}
void cvFindTarget(const IplImage* img_,CvTarget& tar)
{
assert(img_->nChannels==1);
IplImage* img=cvCreateImage(cvSize(img_->width,img_->height),IPL_DEPTH_8U,1);
cvCopy(img_,img);
for (int h=0;h<img->height;h++){
for (int w=0;w<img->width;w++){
if (*(unsigned char*)(img->imageData+h*img->widthStep+w)==255){
CvTarget target;
target.top=h;
target.bottom=h;
target.left=w;
target.right=w;
queue<CvPoint> points;
points.push(cvPoint(w,h));
*(img->imageData+h*img->widthStep+w)=0;
//find target with breadth iteration
while(!points.empty()){
target.erea++;
CvPoint p=points.front();
points.pop();
if (p.x>0&&*(unsigned char*)(img->imageData+p.y*img->widthStep+p.x-1)==255){//left
*(img->imageData+p.y*img->widthStep+p.x-1)=0;
points.push(cvPoint(p.x-1,p.y));
if (target.left>p.x-1){
target.left=p.x-1;
}
}
if (p.y+1<img->height&&*(unsigned char*)(img->imageData+(p.y+1)*img->widthStep+p.x)==255){//bottom
*(img->imageData+(p.y+1)*img->widthStep+p.x)=0;
points.push(cvPoint(p.x,p.y+1));
if (target.bottom<p.y+1){
target.bottom=p.y+1;
}
}
if (p.x+1<img->width&&*(unsigned char*)(img->imageData+p.y*img->widthStep+p.x+1)==255){//right
*(img->imageData+p.y*img->widthStep+p.x+1)=0;
points.push(cvPoint(p.x+1,p.y));
if (target.right<p.x+1){
target.right=p.x+1;
}
}
if (p.y>0&&*(unsigned char*)(img->imageData+(p.y-1)*img->widthStep+p.x)==255){//top
*(img->imageData+(p.y-1)*img->widthStep+p.x)=0;
points.push(cvPoint(p.x,p.y-1));
}
}
if (target.erea>tar.erea){
tar=target;
}
}
}
}
cvReleaseImage(&img);
}
- 1
- 2
- 3
- 4
前往页