首页 > 代码库 > 用opencv读取图像鼠标点的像素,更正一个Bug

用opencv读取图像鼠标点的像素,更正一个Bug


作者:skyseraph
出处:http://www.cnblogs.com/skyseraph/

以下代码在网上流传很广。

不过,调试运行之后发现,功能是正确的,但是内存很快就耗尽,导致死机。经过查找,加上:


cvReleaseImage(&img1);    //释放源图像占用的内存


这一行是我(szliug)加的,否则内存很快就会耗尽,会死机的。

之后运行正常。



/*===============================================//

功能:OpenCV Utility: Reading Image Pixels Value
时间:4/4/2011 SkySeraph HQU
//===============================================*/
#include "iostream"
#include "cv.h"
#include "highgui.h"
using namespace std;

#include "math.h"

#pragma comment(lib,"highgui.lib")
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cvaux.lib")
#pragma comment(lib,"cxcore.lib")

//  源图像
const char* filename = "../picture/Flo.jpg";

//  隐藏Console窗口
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )


/*=============================================*/
void mouseHandler(int event, int x, int y, int flags, void* param)
{
    IplImage* img0, * img1;    
    img0 = (IplImage*) param;
    img1 = cvCloneImage(img0);
    /*-------------cvInitFont-------------------//
    //功能:初始化字体结构体
    //原型:void cvInitFont(
        CvFont* font, //被初始化的字体结构体
        int font_face,//字体名称标识符
            $ CV_FONT_HERSHEY_SIMPLEX - 正常大小无衬线字体。
            $ CV_FONT_HERSHEY_PLAIN - 小号无衬线字体。
            $ CV_FONT_HERSHEY_DUPLEX - 正常大小无衬线字体。( 比CV_FONT_HERSHEY_SIMPLEX更复杂)
            $ CV_FONT_HERSHEY_COMPLEX - 正常大小有衬线字体。
            $ CV_FONT_HERSHEY_TRIPLEX - 正常大小有衬线字体 ( 比CV_FONT_HERSHEY_COMPLEX更复杂)
            $ CV_FONT_HERSHEY_COMPLEX_SMALL - CV_FONT_HERSHEY_COMPLEX 的小译本。
            $ CV_FONT_HERSHEY_SCRIPT_SIMPLEX - 手写风格字体。
            $ CV_FONT_HERSHEY_SCRIPT_COMPLEX - 比CV_FONT_HERSHEY_SCRIPT_SIMPLEX更复杂。
            //这个参数能够由一个值和可选择的CV_FONT_ITALIC字体标记合成,就是斜体字
        double hscale,//字体宽度。
            //如果等于1.0f,字符的宽度是最初的字体宽度。如果等于0.5f,字符的宽度是最初的字体宽度的一半
        double vscale,//字体高度。
        double shear=0,//字体的斜度。
            //当值为0时 ,字符不倾斜;当值为1.0f时,字体倾斜≈45度,等等。厚度让字母着重显示。函数cvLine用于绘制字母
        int thickness=1, //字体笔划的粗细程度
        int line_type=8 //字体笔划的类型
        );
    //--------------------------------------------*/
    CvFont font;
    uchar* ptr;
    char label[20];
    cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, .8, .8, 0, 1, 8);
    if (event == CV_EVENT_LBUTTONDOWN) //单击左键
    {
        /* read pixel */
        ptr = cvPtr2D(img1, y, x, NULL);//返回指向特殊数组元素的指针 && cvGet2D返回指向特殊数组的元素
        /*display the BGR value*/
        sprintf(label, "(%d, %d, %d)", ptr[0], ptr[1], ptr[2]);
        cvRectangle(
            img1,
            cvPoint(x, y - 12),
            cvPoint(x + 100, y + 4),
            CV_RGB(255, 0, 0),
            CV_FILLED,
            8, 0
            );
        cvPutText(
            img1,
            label,
            cvPoint(x, y),
            &font,
            CV_RGB(255, 255, 0)
            );
        cvShowImage("img", img1);
    }

    cvReleaseImage(&img1);    //释放源图像占用的内存,这一行是我(szliug)加的,否则内存很快就会耗尽,会死机的。

}

int main(int argc, char** argv)
{
    IplImage* img;
    /* usage: <prog_name> <image> */
    //if (argc != 2)
    //{
    //    printf("Usage: %s <image>\n", argv[0]);
    //    return 1;
    //}
    /* load image */
    img = cvLoadImage(filename, 1);
    /* always check */
    assert(img);
    /* create a window and install mouse handler */
    cvNamedWindow("img", 1);
    //  注册鼠标事件
    cvSetMouseCallback("img", mouseHandler, (void*)img);
    cvShowImage("img", img);
    cvWaitKey(0);
    /* be tidy */
    cvDestroyAllWindows();
    cvReleaseImage(&img);
    return 0;
}