• 《学习OpenCV》练习题第四章第三题b


      1 #include <highgui.h>
      2 #include <cv.h>
      3 #include "opencv_libs.h"
      4 
      5 /*
      6  *《学习OpenCV》第四章第三题b
      7  * 完成时间:1:36 3/31 星期日 2013
      8  */
      9 
     10 /* 矩形框 */
     11 CvRect rect;
     12 
     13 bool draw = false;   // 标记是否在画
     14 
     15 IplImage* img;
     16 IplImage * temp;
     17 IplImage * original;
     18 
     19 bool draw_hist = false;
     20 
     21 IplImage* getHistImage(IplImage* image, CvHistogram* image_hist, 
     22                        CvSize image_size, CvScalar value)
     23 {
     24     // 计算直方图
     25     cvCalcHist( &image, image_hist, 0, NULL );
     26     // 新建一幅3通道的图像
     27     IplImage* dst = cvCreateImage(image_size, IPL_DEPTH_8U, 3 );
     28     
     29     cvSet( dst, cvScalarAll(255) );
     30     
     31     float max_value = 0;
     32     cvGetMinMaxHistValue( image_hist, NULL, &max_value, NULL, NULL );
     33     double bin_width = (double)dst->width/256;
     34     double bin_unith = (double)dst->height/max_value;   // 高度比例
     35 
     36     for(int i = 0; i < 256; i++)
     37     {
     38         // 获得矩形左上角和右下角坐标
     39         CvPoint p0 = cvPoint( i + bin_width, dst->height );
     40         CvPoint p1 = cvPoint( (i+1) * bin_width, 
     41             dst->height - cvGetReal1D(image_hist->bins, i) *  bin_unith );
     42         // 画实心矩形
     43         cvRectangle( dst, p0, p1, value, -1, 8, 0 );
     44     }
     45 
     46     return dst;
     47 }
     48 
     49 void draw_rect(IplImage* img, CvRect rect)
     50 {
     51     cvRectangle( img, 
     52         cvPoint( rect.x, rect.y ),
     53         cvPoint( rect.x + rect.width, rect.y + rect.height),
     54         cvScalar( 0x00, 0x00, 0xff) );
     55     printf("draw
    ");
     56 
     57     // 在这里处理直方图
     58     // 设置感兴趣区域
     59     cvSetImageROI( img, rect);
     60     IplImage* src_rect = cvCreateImage ( 
     61         cvSize( rect.width, rect.height ), 
     62         img->depth, img->nChannels );
     63     cvCopy(img, src_rect );
     64     cvResetImageROI( img );
     65 
     66     IplImage* r_img = cvCreateImage( cvGetSize( src_rect),
     67         src_rect->depth, 1 );
     68     IplImage* g_img = cvCreateImage( cvGetSize( src_rect),
     69         src_rect->depth, 1 );
     70     IplImage* b_img = cvCreateImage( cvGetSize( src_rect),
     71         src_rect->depth, 1 );
     72     IplImage* gray_img = cvCreateImage( cvGetSize( src_rect),
     73         src_rect->depth, 1 );
     74     
     75     // 分离RGB分量
     76     cvSplit( src_rect, r_img, g_img, b_img, NULL);
     77     cvShowImage( "red", r_img);
     78     cvShowImage( "green", g_img);
     79     cvShowImage( "blue", b_img);
     80     
     81     // 灰度转换
     82     cvCvtColor( src_rect, gray_img, CV_BGR2GRAY);
     83     int size = 256;
     84     float range[] = {0, 255};
     85     float* ranges[] = {range};
     86     // 创建直方图
     87     CvHistogram * r_hist = cvCreateHist( 1, &size, CV_HIST_ARRAY, ranges, 1);
     88     CvHistogram * g_hist = cvCreateHist( 1, &size, CV_HIST_ARRAY, ranges, 1);
     89     CvHistogram * b_hist = cvCreateHist( 1, &size, CV_HIST_ARRAY, ranges, 1);
     90     CvHistogram * gray_hist = cvCreateHist( 1, &size, CV_HIST_ARRAY, ranges, 1);
     91 
     92     // 直方图尺寸
     93     CvSize image_size = cvSize( 400, 300);
     94     
     95     IplImage* r_dst = getHistImage(r_img, r_hist, image_size, cvScalar(0x00, 0x00, 0xff));
     96     IplImage* g_dst = getHistImage(g_img, g_hist, image_size, cvScalar(0x00, 0xff, 0x00));
     97     IplImage* b_dst = getHistImage(b_img, b_hist, image_size, cvScalar(0xff, 0x00, 0x00));
     98     IplImage* gray_dst = getHistImage( gray_img, gray_hist, image_size, cvScalar(0) );
     99 
    100     // 把四个直方图在一幅图片上显示出来
    101     IplImage* dst = cvCreateImage( cvSize( image_size.width * 2, image_size.height * 2), 8, 3 );
    102     cvSetZero( dst );
    103     // 拷贝红色分量直方图
    104     CvRect r_rect = cvRect( 0, 0, image_size.width, image_size.height);
    105     cvSetImageROI(dst, r_rect);
    106     cvCopy( r_dst, dst);
    107     // 拷贝绿色分量直方图
    108     CvRect g_rect = cvRect(image_size.width, 0, image_size.width, image_size.height );
    109     cvSetImageROI( dst, g_rect);
    110     cvCopy( g_dst, dst);
    111     // 蓝色分量
    112     CvRect b_rect = cvRect(0, image_size.height, image_size.width, image_size.height );
    113     cvSetImageROI(dst, b_rect);
    114     cvCopy( b_dst, dst );
    115     // 灰度分量
    116     CvRect gray_rect = cvRect( image_size.width, image_size.height, 
    117         image_size.width, image_size.height );
    118     cvSetImageROI( dst, gray_rect);
    119     cvCopy( gray_dst, dst);
    120 
    121     cvResetImageROI( dst );
    122 
    123     cvShowImage( "src", src_rect);
    124     cvShowImage( "dst", dst );
    125 
    126     cvWaitKey(0);
    127 
    128     cvDestroyAllWindows();
    129     cvReleaseImage( &r_img );
    130     cvReleaseImage(&g_img);
    131     cvReleaseImage(&b_img);
    132     cvReleaseImage(&gray_img);
    133     cvReleaseImage(&r_dst);
    134     cvReleaseImage(&g_dst);
    135     cvReleaseImage(&b_dst);
    136     cvReleaseImage(&gray_dst);
    137     cvReleaseImage(&src_rect);
    138     cvReleaseImage(&dst);
    139 }
    140 
    141 // 鼠标回调函数
    142 void my_mouse_callback( int event, int x, int y, int flags, void* param)
    143 {
    144     IplImage* image = (IplImage*) param;
    145 
    146     switch( event )
    147     {
    148     case CV_EVENT_MOUSEMOVE:
    149         {
    150             if(draw)
    151             {
    152                 rect.width = x - rect.x;
    153                 rect.height = y - rect.y;
    154             }
    155 
    156             draw_hist = false;
    157         }
    158         break;
    159     case CV_EVENT_LBUTTONDOWN:
    160         {
    161             draw = true;
    162             rect = cvRect( x, y, 0, 0 );
    163             draw_hist = false;
    164         }
    165         break;
    166     case CV_EVENT_LBUTTONUP:
    167         {
    168             draw = false;
    169             draw_hist = true;
    170             if(rect.width < 0)
    171             {
    172                 rect.x += rect.width;
    173                 rect.width *= -1;
    174             }
    175             if(rect.height < 0)
    176             {
    177                 rect.y += rect.height;
    178                 rect.height *= -1;
    179             }
    180             // draw
    181             draw_rect(image, rect);
    182         }
    183         break;
    184         // 在右键按下时清除
    185     case CV_EVENT_RBUTTONDOWN:
    186         cvCopyImage(original, img);
    187         printf("clear.
    ");
    188         break;
    189     }
    190 }
    191 
    192 int main()
    193 {
    194     img = cvLoadImage( "lena.bmp", 1 );
    195 
    196     rect = cvRect( -1, -1, 0, 0);
    197     
    198     // 副本
    199     temp = cvCloneImage( img );
    200     original = cvCloneImage(img);
    201     
    202     cvNamedWindow("draw rect");
    203     cvSetMouseCallback("draw rect", my_mouse_callback, (void*)img);
    204 
    205     while(1)
    206     {
    207         cvCopyImage(img, temp);
    208 
    209         if(draw_hist)
    210         {
    211             draw_rect( temp , rect );
    212         }
    213 
    214         cvShowImage( "draw rect", temp);
    215 
    216         if(cvWaitKey(15) == 27)
    217             break;
    218     }
    219     cvReleaseImage(&img);
    220     cvReleaseImage(&temp);
    221     cvDestroyAllWindows();
    222 
    223     return 0;
    224 }

    运行结果:

    不足:在源图像上用鼠标选择矩形区域的时候,无法实时地在图像上反映出来。

  • 相关阅读:
    dubbo的超时机制
    今天又遇到之前的问题,后端返回数据long到前端失真
    如何在一台机子上配置两个github
    当sum函数返回null时处理
    Linux中zookeeper安装
    Linux常用指令
    sql执行顺序
    固定时间刷新某个固定值 java
    docker基础
    python之CSS
  • 原文地址:https://www.cnblogs.com/qdsclove/p/3351188.html
Copyright © 2020-2023  润新知