2 lblackcat LBlackCat 于 2015.06.03 20:18 提问

要做一个C++项目 关于自动抠像的
c++

VS2010 在新建项目的时候 我该用控制台应用程序呢 还是win32程序创建项目呢? 求解释 我们在学C++的时候一直在用控制台应用程序 可是 要做项目 不应该是有界面 可视度比较强的项目吗 但是 并没有学过win32编程诶。。 这个不需要另外学吗。。

5个回答

autocyz
autocyz   2015.06.03 20:22

这要看你的算法主要不主要了,现在处理方面有一些库,实际上你只需要是控制台应用就行,一些界面可以调用库里

wangxlk21
wangxlk21   2015.06.03 21:41

可以调用库函数来实现

PTS872001488
PTS872001488   2015.06.04 08:49

控制台应用程序
#include "cv.h"
#include "highgui.h"
#include
#include

#pragma comment(lib, "opencv_core2410d.lib")
#pragma comment(lib, "opencv_highgui2410d.lib")
#pragma comment(lib, "opencv_imgproc2410d.lib")
#pragma comment(lib, "opencv_objdetect2410d.lib")
#pragma comment(lib, "opencv_video2410d.lib")

#pragma comment(lib, "libjasperd.lib")
#pragma comment(lib, "IlmImfd.lib")
#pragma comment(lib, "libjpegd.lib")
#pragma comment(lib, "libpngd.lib")
#pragma comment(lib, "libtiffd.lib")
#pragma comment(lib, "zlibd.lib")

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")

#pragma comment( lib, "vfw32.lib" )

#pragma comment( lib, "comctl32.lib" )

static CvMemStorage*storage = 0;
static CvHaarClassifierCascade*cascade = 0;
void detect_and_draw(IplImage* image);
const char*cascade_name = "haarcascade_frontalface_alt.xml";//人脸检测分类器

IplImage image_c = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0;
//用HSV中的Hue分量进行跟踪
CvHistogram *hist = 0;//直方图类
int select_object = 0;
int track_object = 0;
CvPoint origin;
CvRect selection;
CvRect track_window;
CvBox2D track_box;
CvConnectedComp track_comp;
int hdims = 16;//划分直方图bins的个数,越多越精确
float hranges_arr[] = { 0, 180 };//像素值的范围
float
hranges = hranges_arr;//用于初始化CvHistogram类
int vmin = 10, vmax = 256, smin = 30;//用于范围
void on_mouse(int event, int x, int y, int flags, void* param);
CvScalar hsv2rgb(float hue);

int on_off = 0;
int main(int argc, char**argv)
{
CvCapture* capture = 0;
IplImage frame, *frame_copy = 0;
const char*input_name;
char c;
input_name = argc> 1 ? argv[1] : 0;
cascade = (CvHaarClassifierCascade
)cvLoad(cascade_name, 0, 0, 0);
if (!cascade)//如果没有找到分类器,输出以下
{
fprintf(stderr,"ERROR: Could notload classifier cascade\n");
return -1;
}
storage = cvCreateMemStorage(0);
capture = cvCaptureFromCAM(!input_name ? 0 : input_name[0] - '0');//读取摄像头
if(!capture)//如果没有摄像头读取视频文件
capture = cvCaptureFromAVI("检测.avi");
cvNamedWindow("result", 1);//创建窗口

cvSetMouseCallback("result", on_mouse, 0);//设置鼠标回调函数

if (capture) 
{
    for (;;) 
    {
        frame = cvQueryFrame(capture);
        if (!frame)
            break;
        if( !frame_copy) 
            frame_copy= cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U,frame->nChannels ); 
        if (on_off)
        {
            if (frame->origin == IPL_ORIGIN_TL)
                cvCopy(frame, frame_copy, 0);
            else cvFlip(frame, frame_copy, 0);
            detect_and_draw(frame_copy);
        }
        else
        {
            if (!image_c)//image为0,表明刚开始还未对image操作过,先建立一些缓冲区
            {
                image_c = cvCreateImage(cvGetSize(frame), 8, 3);
                image_c->origin = frame->origin;
                hsv = cvCreateImage(cvGetSize(frame), 8, 3);
                hue = cvCreateImage(cvGetSize(frame), 8, 1);
                mask = cvCreateImage(cvGetSize(frame), 8, 1);
                //分配掩膜图像空间
                backproject = cvCreateImage(cvGetSize(frame), 8, 1);
                //分配反向投影图空间,大小一样,单通道
                hist = cvCreateHist(1, &hdims, CV_HIST_ARRAY, &hranges, 1);
                //分配直方图空间
            }
            cvCopy(frame, image_c, 0);
            cvCvtColor(image_c, hsv, CV_BGR2HSV);//把图像从RGB表色系转为HSV表色系
            if (track_object)//track_object非零,表示有需要跟踪的物体
            {
                cvInRangeS(hsv, cvScalar(0, smin, MIN(vmin, vmax), 0),
                    cvScalar(180, 256, MAX(vmin, vmax), 0), mask);
                //制作掩膜板,只处理像素值为H:0~180,S:smin~256,V:vmin~vmax之间的部分
                cvSplit(hsv, hue, 0, 0, 0);//分离H分量
                if (track_object < 0)
                    //如果需要跟踪的物体还没有进行属性提取,则进行选取框类的图像属性提取
                {
                    float max_val = 0.f;
                    cvSetImageROI(hue, selection);//设置原选择框为ROI
                    cvSetImageROI(mask, selection);//设置掩膜板选择框为ROI
                    cvCalcHist(&hue, hist, 0, mask);//得到选择框内且满足掩膜板内的直方图
                    cvGetMinMaxHistValue(hist, 0, &max_val, 0, 0);
                    cvConvertScale(hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0);
                    // 对直方图的数值转为0~255
                    cvResetImageROI(hue);//去除ROI
                    cvResetImageROI(mask);//去除ROI
                    track_window = selection;
                    track_object = 1;//置track_object为1,表明属性提取完成
                }
                cvCalcBackProject(&hue, backproject, hist);//计算hue的反向投影图
                cvAnd(backproject, mask, backproject, 0);//得到掩膜内的反向投影
                cvCamShift(backproject, track_window,
                    cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1),
                    &track_comp, &track_box);//使用MeanShift算法对backproject中的内容进行搜索,返回跟踪结果
                track_window = track_comp.rect;//得到跟踪结果的矩形框

                if (image_c->origin)
                    track_box.angle = -track_box.angle;
                cvEllipseBox(image_c, track_box, CV_RGB(255, 0, 0), 3, CV_AA, 0);
                //画出跟踪结果的位置
            }
            if (select_object && selection.width > 0 && selection.height > 0)//如果正处于物体选择,画出选择框
            {
                cvSetImageROI(image_c, selection);
                cvXorS(image_c, cvScalarAll(255), image_c, 0);
                cvResetImageROI(image_c);
            }
            cvShowImage("result", image_c);
        }
        c = cvWaitKey(10);
        if ((char)c == 27)
            break;
        else if ((char)c == 'b')
            on_off = 1 - on_off;

    }
    cvReleaseImage(&frame_copy); 
    cvReleaseCapture(&capture);
}
cvDestroyWindow("result");
return 0;

}
void on_mouse(int event, int x, int y, int flags, void* param)
//鼠标回调函数,该函数用鼠标进行跟踪目标的选择
{
if (!image_c)
return;
if (image_c->origin)
y = image_c->height - y;//如果图像原点坐标在左下,则将其改为左上
if (select_object)//select_object为1,表示在用鼠标进行目标选择
//此时对矩形类selection用当前的鼠标位置进行设置
{
selection.x = MIN(x, origin.x);
selection.y = MIN(y, origin.y);
selection.width = selection.x + CV_IABS(x - origin.x);
selection.height = selection.y + CV_IABS(y - origin.y);

    selection.x = MAX(selection.x, 0);
    selection.y = MAX(selection.y, 0);
    selection.width = MIN(selection.width, image_c->width);
    selection.height = MIN(selection.height, image_c->height);
    selection.width -= selection.x;
    selection.height -= selection.y;
}
switch (event)
{
case CV_EVENT_LBUTTONDOWN:
    //鼠标按下,开始点击选择跟踪物体
    origin = cvPoint(x, y);
    selection = cvRect(x, y, 0, 0);
    select_object = 1;
    break;
case CV_EVENT_LBUTTONUP:
    //鼠标松开,完成选择跟踪物体
    select_object = 0;
    if (selection.width > 0 && selection.height > 0)
        //如果选择物体有效,则打开跟踪功能
        track_object = -1;
    break;
}

}
CvScalar hsv2rgb(float hue)//用于将Hue量转换成RGB量
{
int rgb[3], p, sector;
static const int sector_data[][3] =
{ { 0, 2, 1 }, { 1, 2, 0 }, { 1, 0, 2 }, { 2, 0, 1 }, { 2, 1, 0 }, { 0, 1, 2 } };
hue *= 0.033333333333333333333333333333333f;
sector = cvFloor(hue);
p = cvRound(255 * (hue - sector));
p ^= sector & 1 ? 255 : 0;

rgb[sector_data[sector][0]] = 255;
rgb[sector_data[sector][1]] = 0;
rgb[sector_data[sector][2]] = p;


return cvScalar(rgb[2], rgb[1], rgb[0], 0);

}
void detect_and_draw(IplImage* img)
{
static CvScalar colors[] =
{
{ { 0, 0, 255 } },
{ { 0, 128, 255 } },
{ { 0, 255, 255 } },
{ { 0, 255, 0 } },
{ { 255, 128, 0 } },
{ { 255, 255, 0 } },
{ { 255, 0, 0 } },
{ { 255, 0, 255 } }
};
double scale = 1.3;
IplImage* gray = cvCreateImage(cvSize(img->width, img->height), 8, 1);
IplImage* small_img = cvCreateImage(cvSize(cvRound(img->width / scale), cvRound(img->height / scale)), 8, 1);
int i;
cvCvtColor(img, gray, CV_BGR2GRAY);
cvResize(gray, small_img, CV_INTER_LINEAR);
cvEqualizeHist(small_img, small_img);
cvClearMemStorage(storage);
if (cascade)
{
double t = (double)cvGetTickCount();
CvSeq* faces = cvHaarDetectObjects(small_img, cascade, storage, 1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/, cvSize(30, 30));//检测人脸返回矩形人脸
t = (double)cvGetTickCount() - t;
printf("detection time = %gms\n", t / ((double)cvGetTickFrequency()*1000.));
for (i = 0; i < (faces ? faces->total : 0); i++)//找到矩形中心,把矩形转化为圆形
{
CvRect*r = (CvRect*)cvGetSeqElem(faces, i);
CvPoint center;
int radius;
center.x = cvRound((r->x + r->width*0.5)*scale);
center.y = cvRound((r->y + r->height*0.5)*scale);
radius = cvRound((r->width + r->height)*0.25*scale);
cvCircle(img, center, radius, colors[i % 8], 3, 8, 0);
}
}
cvShowImage("result", img);
cvReleaseImage(&gray);
cvReleaseImage(&small_img);
}

u012061345
u012061345   2015.06.04 16:58

控制台程序还是win32程序,是你的程序的交互方式。无论哪种交互方式,肯定都能实现抠像的算法。
交互方式和抠像本身没有必然的联系。到底选哪种,当然看你的设计需要。
不过推荐使用OpenCV做控制台程序。这样可以专心实现抠像算法本身,而不必再去学习可视化程序设计。

datou431
datou431   Rxr 2015.06.18 11:06

可以调用库函数来实现

Csdn user default icon
上传中...
上传图片
插入图片