想用OpenCV观察图像数据?这里是详解

来源:互联网 发布:insar数据购买 编辑:程序博客网 时间:2024/06/03 07:11

如果你对通用RGB图像数据的结构感兴趣,这里有一个简单的办法以满足你的好奇心:

目标:一个能读取图像指定区域像素的工具.

附加要求:能从拖动读取,多次指定不同区域,能将区域的图形显示出来.

1首先你需要按照OpenCV.这个著名的开源视觉库非常友好.

2你需要一个VisualStudio2010起码.

ok.

3设置好你的项目属性管理器.

4代码

Beta0.1
//包含你用到的代码仓库//opencv库#include <opencv2/opencv.hpp>//C++标准输入输出库,用来获取键盘输入(cin)和输入(cout)指定范围内的数据#include <iostream>//标准C库,这里使用了getchar()使程序在最后暂停显示信息.当然你还可以使用waitKey(0)//但是它在图形界面,也就是OpenCV显示图片的时候才有效.这里已经没有图片了.#include <stdio.h>//将"命名空间"包含进来,方便我们使用,你也可以using std::cin;只一条条写出自己需要的名字.//这样不会将大量的名字通通放在自己的范围,防止冲突.using namespace cv;using namespace std;//这一大串可不是我手写的,它是Visual Assist X一款VS的插件生成的.我们这次只需要它第二个参数//这个函数可疑简写为int main(int _Argc,char** _Argv),你应当了解它们的含义int main(_In_ int _Argc, _In_reads_(_Argc) _Pre_z_ char ** _Argv, _In_z_ char ** _Env){//_Argc表示命令行参数个数,第一个自动为自己程序的路径,所以如果大于1个表示有参数传入//这里将数字放在开头是为了防止出现赋值错误的一种书写习惯.比如if(2=i)和if(2==i),前者编译器会提醒你并阻止你    if (2<=_Argc)    {    //_Argv[1]保存了传入的参数,也就是拖动图片到本程序上,图片的路径        //Mat是一个类似于int的东西,用来声明一个空间用来存放我们的图片数据        Mat srcImage=imread(_Argv[1],2|4);        if (NULL==srcImage.data)        {            puts("目标是图片吗?");            fflush(stdin);            getchar();            //这是一个退出函数,非0代表异常,给自己看的            exit(-1);        }        int colsF,rowsF,colsE,rowsE;        cout<<"输入查看图像的两个坐标eg:10,20,30,40"<<endl;        //一个循环用来重复"输入-显示"        while(true)        {        //通过传入4个参数指定你想要显示的图片范围        cin>>colsF>>rowsF>>colsE>>rowsE;        //销毁窗口A,便于下一次创建新的展示窗口        destroyWindows("A");        //很有含金量的句子,标记一个"感兴趣范围"用来显示        Mat imageROI=srcImage(Rect(colsF,rowsF,colsE,rowsE));        //显示它在A窗口.        imshow("A",imageROI);        cout<<_Argv<<"的矩阵为:"<<endl<<imageROI<<endl<<endl;        //fflush是一个有趣的函数,它在这里用来清理输入输出的缓冲区,        //防止waitKey将上次的结果当成这次的输入(谁让计算机速度这么快呢)        fflush(stdin);        if( waitKey( 10 ) == 27 ) break;//Esc退出        }        return 0;    }    puts("这个工具运行在命令行参数下");    fflush(stdin);    getchar();    //返回0代表正常,返回非0值一般代表异常.    exit(-2);}

以上代码结果是:指定范围内的数据可以正常展示,但是图片不能显示出来,一直在闪动.
可能的原因是单线程占用(好不专业的说法)

所以有了

Beta0.2

我创始建立一个多线程程序.图片显示和数据显示互不干涉,和平共处……
最简单多线程程序创建参考这里.

#include <opencv2/opencv.hpp>#include <iostream>#include <stdio.h>//因为要多线程嘛,自然要包含Windows的"头文件"啦#include <Windows.h>using namespace cv;using namespace std;//一个"全局变量",便于从独立的线程操控我们的图像数据Mat imageROI;//简易却不简单的多线程函数DWORD WINAPI DisplayImage(LPVOID pM)  {      imshow("A",imageROI);    waitKey(0);    return 0;  }  //这次我们将标记,显示等工作独立成一个函数int work(char** _Argv){    Mat srcImage=imread(_Argv[1],2|4);    if (NULL==srcImage.data)    {        puts("目标是图片吗?");        fflush(stdin);        getchar();        exit(-1);    }    int colsF,rowsF,colsE,rowsE;    cout<<"输入查看图像的两个坐标eg:10,20,30,40"<<endl;    while(true)    {        cin>>colsF>>rowsF>>colsE>>rowsE;        destroyWindow("A");        imageROI=srcImage(Rect(colsF,rowsF,colsE,rowsE));        HANDLE handle = CreateThread(NULL, 0, DisplayImage, NULL, 0, NULL);          cout<<_Argv<<"的矩阵为:"<<endl<<imageROI<<endl<<endl;        fflush(stdin);        if( waitKey( 10 ) == 27 )        {            break;//Esc退出        }    }    return 0;}//我们的主函数变得多么简单明了!int main(int _Argc,char** _Argv){    if (2<=_Argc)    {        work(_Argv);    }    puts("这个工具运行在命令行参数下");    fflush(stdin);    getchar();    return (-1);}

上图
如果不拖动图片到我们的程序上,而是直接双击则显示:
直接运行
正常工作:
小图为目标区域,大图为原始图像

好了,有问题讨论哟(~ o ~)~

0 0
原创粉丝点击