【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
opencv是一个公认的图像处理库。就像在3d领域,大家都比较认可pcl点云库一样。在opencv库里面,除了一般的算法之外,还有一个功能比较重要,那就是它还可以实时读取camera的图象。这一点也是很重要的。不然,很多时候,不管是windows平台,还是linux平台,我们需要自己来做这个事情,这就很麻烦。所以,哪怕是非标领域,工控领域,也是可以用easyx做一些事情的。当然,opencv能做的很多,我们完全可以把它当成一个好用的第三方库。

1、安装opencv库
nuget上面提供的库比较老,我们最好自己下载比较新的opencv库。比如,我们下载好windows版本之后,其实对应的头文件目录、lib目录、lib文件、dll文件都准备好了。下面我们要做的,就是把他们用起来。
2、创建工程
在创建好工程之后,需要设置后头文件目录和lib目录,这样才能编译过、链接过。
3、设置好lib
对于需要的lib文件,可以直接在代码中写好,比如这样,
#pragma comment(lib, "opencv_world480d.lib") // download opencv 4.8.0 first
4、准备好usb camera
实际上来说,camera一般分成了这么三种。一种是基于网络的camera,比如带有rtsp协议的这种网络相机。还有一种是usb camera,这种camera比较方便,内部isp都是调好的。最后一种就是mipi camera,这种多用于嵌入式场景。使用起来也是比较方便的。就是isp tunning比较复杂,实际使用的时候需要做好内部设计。
5、实现opencv Mat和easyx数据的转换
因为需要从opencv实时捕捉camera的图象,那么最好还是采用直接显存操作的方法解决,这是比较好的。但是opencv的数据格式,和easyx的数据有点差别,因此有必要写一个转换函数,
void MatToIMAGE(const Mat& mat, IMAGE* img)
{
int w = mat.cols;
int h = mat.rows;
if (img->getwidth() != w || img->getheight() != h)
{
Resize(img, w, h);
}
DWORD* dst = GetImageBuffer(img); // easyx start address
const uchar* src = mat.data; // camera data
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x+=2)
{
int i = y * w + x/2;
int j = (int)(y * mat.step + x * mat.channels());
uchar b = src[j + 0];
uchar g = src[j + 1];
uchar r = src[j + 2];
dst[i] = RGB(b, g, r);
}
}
}
6、添加其他显示内容
很多广告牌除了视频、图片和动画之外,其实还有很多其他内容,比如文字部分。我们可以象征性添加一些内容,
setbkmode(TRANSPARENT);
settextcolor(YELLOW);
outtextxy(440, 250, L"Live Video Show");
7、整理和调试
所有条件都满足之后,就可以开始调试了。直接在pc电脑上买你插入usb相机,然后就是配置好opencv,最后就是输入代码,单步调试。因为这里的lib都是基于动态库的,所以最终运行的时候还需要拷贝一下dll文件。这样一个有点意思的是实时camera工具就算是做好了。
#include <graphics.h>
#include <opencv2/opencv.hpp>
#include <conio.h>
using namespace cv;
#pragma comment(lib, "opencv_world480d.lib") // download opencv 4.8.0 first
void MatToIMAGE(const Mat& mat, IMAGE* img)
{
int w = mat.cols;
int h = mat.rows;
if (img->getwidth() != w || img->getheight() != h)
{
Resize(img, w, h);
}
DWORD* dst = GetImageBuffer(img); // easyx start address
const uchar* src = mat.data; // camera data
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x+=2)
{
int i = y * w + x/2;
int j = (int)(y * mat.step + x * mat.channels());
uchar b = src[j + 0];
uchar g = src[j + 1];
uchar r = src[j + 2];
dst[i] = RGB(b, g, r);
}
}
}
int main(int argc, char* argv[])
{
VideoCapture cap(0);
if (!cap.isOpened())
{
printf("Failed to find video source!\n");
return -1;
}
int w = (int)cap.get(CAP_PROP_FRAME_WIDTH);
int h = (int)cap.get(CAP_PROP_FRAME_HEIGHT);
double fps = cap.get(CAP_PROP_FPS);
if (fps <= 1)
{
fps = 30;
}
int delay = (int)(1000.0 / fps);
initgraph(w, h);
BeginBatchDraw();
Mat frame;
IMAGE img;
while (true)
{
cap >> frame;
if (frame.empty())
{
break;
}
MatToIMAGE(frame, &img);
putimage(0, 0, &img);
setbkmode(TRANSPARENT);
settextcolor(YELLOW);
outtextxy(440, 250, L"Live Video Show");
FlushBatchDraw();
// quit when press escape button
if (_kbhit() && _getch() == 27)
{
break;
}
Sleep(delay);
}
EndBatchDraw();
closegraph();
return 0;
}