如果你对通用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 ~)~