OpenCV第四章练习p126_3

参考:http://blog.csdn.net/xiajun07061225/article/details/6716496

运行结果:

以下是b题,程序运行后无法关闭,待研究:

#include <opencv/cv.h>
#include <opencv/highgui.h>

bool g_draw = false;
bool g_draw_hist = false;
CvRect g_box;

// 画矩形
void draw_box(IplImage *image, CvRect rect, CvScalar scalar)
{
    cvRectangle(image,
                cvPoint(rect.x, rect.y),
                cvPoint(rect.x+rect.width, rect.y+rect.height),
                scalar);
    cvShowImage("p126_3", image);
}

// 统计矩形蓝、绿、红像素数量,画直方图
void draw_hist(IplImage *image, CvRect rect)
{
    cvSetImageROI(image, rect);
    IplImage *src = cvCreateImage(
                cvSize(rect.width, rect.height),
                IPL_DEPTH_8U,
                3);
    cvCopy(image, src);
    cvResetImageROI(image);
    IplImage *r_img = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
    IplImage *g_img = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
    IplImage *b_img = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
    // 分离B,G,R分量
    cvSplit(src, b_img, g_img, r_img, NULL);

    int size = 256;
    float range[] = {0,255};
    float *ranges[] = {range};
    // 创建直方图
    CvHistogram* r_hist = cvCreateHist(1, &size, CV_HIST_ARRAY, ranges, 1);
    CvHistogram* g_hist = cvCreateHist(1, &size, CV_HIST_ARRAY, ranges, 1);
    CvHistogram* b_hist = cvCreateHist(1, &size, CV_HIST_ARRAY, ranges, 1);

    // 红色分量
    cvCalcHist(&r_img, r_hist, 0, NULL);
    IplImage *r_dst = cvCreateImage(cvSize(400,300), IPL_DEPTH_8U, 3);
    cvSet(r_dst, cvScalarAll(255), 0);
    float r_max = 0;
    cvGetMinMaxHistValue(r_hist, NULL, &r_max, NULL, NULL);
    double r_bin_width = (double)r_dst->width / size;
    double r_bin_unith = (double)r_dst->height / r_max;// 高度比例
    for(int i = 0; i<size; i++){
        // 获得矩阵左上角和右下角坐标
        CvPoint p0 = cvPoint(i * r_bin_width, r_dst->height);
        CvPoint p1 = cvPoint((i + 1) * r_bin_width,
                             r_dst->height - cvGetReal1D(r_hist->bins,i) * r_bin_unith);
        cvRectangle(r_dst, p0, p1, cvScalar(255,0,0), -1, 8, 0);// 画实心矩形
    }
    cvNamedWindow("p126_3_r", CV_WINDOW_AUTOSIZE);
    cvShowImage("p126_3_r", r_dst);

    // 绿色分量
    cvCalcHist(&g_img, g_hist, 0, NULL);
    IplImage *g_dst = cvCreateImage(cvSize(400,300), IPL_DEPTH_8U, 3);
    cvSet(g_dst, cvScalarAll(255), 0);
    float g_max = 0;
    cvGetMinMaxHistValue(g_hist, NULL, &g_max, NULL, NULL);
    double g_bin_width = (double)g_dst->width / size;
    double g_bin_unith = (double)g_dst->height / g_max;// 高度比例
    for(int i = 0; i<size; i++){
        // 获得矩阵左上角和右下角坐标
        CvPoint p0 = cvPoint(i * g_bin_width, g_dst->height);
        CvPoint p1 = cvPoint((i + 1) * g_bin_width,
                             g_dst->height - cvGetReal1D(g_hist->bins,i) * g_bin_unith);
        cvRectangle(g_dst, p0, p1, cvScalar(255,0,0), -1, 8, 0);// 画实心矩形
    }
    cvNamedWindow("p126_3_g", CV_WINDOW_AUTOSIZE);
    cvShowImage("p126_3_g", g_dst);

    // 蓝色分量
    cvCalcHist(&b_img, b_hist, 0, NULL);
    IplImage *b_dst = cvCreateImage(cvSize(400,300), IPL_DEPTH_8U, 3);
    cvSet(b_dst, cvScalarAll(255), 0);
    float b_max = 0;
    cvGetMinMaxHistValue(b_hist, NULL, &b_max, NULL, NULL);
    double b_bin_width = (double)b_dst->width / size;
    double b_bin_unith = (double)b_dst->height / b_max;// 高度比例
    for(int i = 0; i<size; i++){
        // 获得矩阵左上角和右下角坐标
        CvPoint p0 = cvPoint(i * b_bin_width, b_dst->height);
        CvPoint p1 = cvPoint((i + 1) * b_bin_width,
                             b_dst->height - cvGetReal1D(b_hist->bins,i) * b_bin_unith);
        cvRectangle(b_dst, p0, p1, cvScalar(255,0,0), -1, 8, 0);// 画实心矩形
    }
    cvNamedWindow("p126_3_b", CV_WINDOW_AUTOSIZE);
    cvShowImage("p126_3_b", b_dst);

    cvWaitKey(0);
    cvDestroyWindow("p126_3_r");
    cvDestroyWindow("p126_3_g");
    cvDestroyWindow("p126_3_b");
}

void my_mouse_callback(int event,
                       int x,
                       int y,
                       int flags,
                       void *param)
{
    IplImage *temp = cvCloneImage((IplImage *)param);// 用局部变量保存副本,这样就不用显式释放
    switch(event){
    case CV_EVENT_LBUTTONDOWN:
    case CV_EVENT_RBUTTONDOWN:{
        g_draw = true;
        g_box = cvRect(x, y, 0, 0);
        break;
    }
    case CV_EVENT_MOUSEMOVE:{
        if(g_draw){
            g_box.width = x - g_box.x;
            g_box.height = y - g_box.y;
            if(g_box.width<0){
                g_box.x += g_box.width;
                g_box.width *= -1;
            }
            if(g_box.height<0){
                g_box.y += g_box.height;
                g_box.height *= -1;
            }
            draw_box(temp, g_box, cvScalar(0x00,0x00,0xff));
        }

        break;
    }
    case CV_EVENT_LBUTTONUP:
    case CV_EVENT_RBUTTONUP:{
        g_draw = false;
        draw_box(temp, g_box, cvScalar(0xff,0x00,0x00));
        draw_hist(temp, g_box);
        break;
    }
    default:
        g_draw = false;
        break;
    }
}

int main(int argc, char *argv[])
{
    char src[] = "F:\\test\\p126_3\\p126_3\\fruits.jpg";
    IplImage *img = cvLoadImage(src, CV_LOAD_IMAGE_COLOR);
    if(!img){
        cvNamedWindow("ERROR", CV_WINDOW_AUTOSIZE);
        cvWaitKey(0);
        return 0;
    }

    cvNamedWindow("p126_3", CV_WINDOW_AUTOSIZE);
    cvShowImage("p126_3", img);
    cvSetMouseCallback("p126_3",
                       my_mouse_callback,
                       (void *)img);
    while(1){
        if(cvWaitKey(33) == 27)
            break;
    }

    cvReleaseImage(&img);
    cvDestroyWindow("p126_3");
    return 1;
}

 

posted on 2013-03-22 16:46  suwen  阅读(210)  评论(0编辑  收藏  举报

导航