Sunday, September 11, 2005

 

Some notes on OpenCV - 1

1.
Intel OpenCV
previous at http://www.intel.com/research/mrl/research/opencv/
and now at http://www.intel.com/technology/computing/opencv/index.htm

you can see the unspoken meaning from the change of address

SOURCEFORGE.NET
http://sourceforge.net/projects/opencvlibrary/

YAHOO OPENCV 的邮件列表:
http://groups.yahoo.com/group/OpenCV/

2.
SharperCV Project
http://www.cs.ru.ac.za/research/groups/SharperCV/

Unfortnately, we're no longer supporting or using SharperCV.
The project was essentially an exercise in investigating interoperability between the managed .NET environment and a substantial "legacy" body of code like OpenCV. Superficially, one can do quite a slick job of making them look compatible. But deep inside, it remains messy. The models for exception handling are completely incompatible, so one can never catch the OpenCV errors like we'd like to. OpenCV requires regular polling in order to service its window and mouse events: this is a mess. The object-oriented approach and organization we'd like to use in C# is not present at all in the "flattened" code model of OpenCV, so there is a mismatch. And there are substantial problems with doing the really interesting things, like handling AVI streams and Windows DirectShow features.

So our own advice and approach has been to abandon SharperCV, and to migrate the little functionality we needed for our own work directly into C#. The single-layer, single-language, single-documentation and single paradigm model has worked out easier for us in the long run.

Thanks to everyone who provided encouragement and feedback about SharperCV. It was fun.

If anyone becomes aware of a high-performance, high-functionality imaging library that is directly usable in .NET, please let us know. OpenCV has many things we like - but then so does C#!

My comment: it is still an interesting approach. Actually, if we do not care about implementing GUI using opencv and just just the functions that supported by opencv, it is good enough!

3.
Wrapping OpenCV with SWIG
http://www.ient.rwth-aachen.de/team/asbach/opencv-python.html

4.
Some interesting tests using SharperCV
http://www.mperfect.net/cameraFlow/

5.
OpenCV 常见问题及解决方法(中文翻译)

常见问题及解决方法

一般性问题
翻译:HUNNISH, 阿须数码


--------------------------------------------------------------------------------

如何正确安装 OpenCV ?
阅读 安装指南


--------------------------------------------------------------------------------

如何快速认识 OpenCV ?

参考 样例。
在 Visual Studio 中加载 OpenCV workspace:
opencv.dsw for Microsoft Visual Studio 6.0
opencv.sln for Miscrosoft Visual Studio .NET 2003
cbuilderx/opencv.bpgr for Borland C++ BuilderX
选择 cvsample 项目,编译并运行。阅读代码并且按照自己的想法更改它。
也可通读 参考手册 - 里面也包含一些样例代码.
搜索 http://groups.yahoo.com/group/OpenCV 中的 OpenCV archives,选择你兴趣的主题。
从 scratch 创建新的项目,或者修改现有的 cvsample。 对 Microsoft Visual Studio 有现成的向导来创建 OPENCV 项目。

--------------------------------------------------------------------------------

哪里可以报告OPENCV的Bug ?
发邮件到 OpenCV@yahoogroups.com Subject: BUG <....your title...>


--------------------------------------------------------------------------------

怎么报告 Intel?Ingegrated Performance Primitives 的BUG?
发邮件到 developer_support@intel.com


--------------------------------------------------------------------------------

怎么加入 OpenCV 论坛?
发邮件 OpenCV-subscribe@yahoogroups.com, 如果你是 YAHOO GROUP 的成员并且已经登陆。你可以在 http://groups.yahoo.com/group/OpenCV 中阅读论坛内容。

NOTE: 上海阿须数码技术有限公司 设立了一个 中文OPENCV论坛,可以在那里找到很多有用资料。


--------------------------------------------------------------------------------

怎么修改用户组设置使得不再收到大量邮件?
想实时接收邮件或一天只接收一次邮件摘要,可以访问 http://groups.yahoo.com/mygroups 然后更改设置。


--------------------------------------------------------------------------------

好,我发现用户组一点没用。如何退掉我订阅的邮件列表?
发邮件到 OpenCV-unsubscribe@yahoogroups.com ,主题 subject 为[OpenCV]


--------------------------------------------------------------------------------

当同时使用 OpenCV 和 IPL,发生编译错误。怎么解决这个问题?
为了完全独立于 IPL (INTEL的图像处理库), OpenCV 复制了 IplImage 和其它一些结构变量的声明。 在 OpenCV 头前面定义 HAVE_IPL 或者将语句 "#include " 放置于 OpenCV 头文件的前面,可以解决这个冲突。


--------------------------------------------------------------------------------

OpenCV 可以工作在其它处理器下吗?
是的,OpenCV 本身是开发源代码的,而且在32位平台上非常紧凑。从另外一方面看,如果采用 INTEL 处理器,那么依靠 IPP ,OpenCV 可以运行得更快。


--------------------------------------------------------------------------------

Windows® 操作系统的相关问题:

--------------------------------------------------------------------------------

当我试图编译其中的应用程序时,得到错误:streams.h 没有发现.
你需要 DirectShow SDK ,它是 DirectX SDK 的一个部分。

从 msdn.microsoft.com/directx/ 下载 DirectX,(文件很大,但是可以只下载部分)。如果不能正常工作,考虑一下 HighGUI 利用 VFW 或 MIL 来扑捉视频序列。
带样例安装 (TOGETHER WITH SAMPLES.)
打开项目 \samples\C++\DirectShow\BaseClasses\baseclasses.{dsw|sln}. 如果没有这个文件,要么是你没有下载样例,要么是路径不对。
编译建立 Release 和 Debug 版本
将产生的库 (在 DirectX 9.x 中,分别叫 strmbase.lib 和 strmbasd.lib) 拷贝到目录 \lib 下。
在 Developer Studio 添加路径:
\include
\samples\C++\DirectShow\BaseClasses


到 includes' 搜索路径中 (在 Tools->Options->Directories->Include files in case of Developer Studio 6.0)

添加 \lib 到库搜索路径中 (在 Tools->Options->Directories->Library files in case of Developer Studio 6.0)

注意: 将上面增加的东东添加到最顶端,否则还会出现编译或链接错误。因为 Developer Studio 6.0 包含了一些老版本的 DirectX 头文件和库文件,它们与新版本有冲突。

大功告成!

--------------------------------------------------------------------------------

安装了 DirectX SDK 后,仍然有链接错误,提示:undefined or redefined "TransInPlace" filter class constructors etc.
阅读前面的示范,特别注意搜索目录的次序。


--------------------------------------------------------------------------------

当我试图使用 cvcam, 程序崩溃
确保注册了 ProxyTrans.ax 和 SyncFilter.ax


--------------------------------------------------------------------------------

怎么注册 *.ax (DirectShow filter)?
运行文件 regsvr32.exe


--------------------------------------------------------------------------------

Filter 不能被注册 (regsvr32 报告错误)
最可能的原因是 filter 需要的一些 DLLs 不在路径中,这种情况下,OpenCV 可以确保 \bin 在路径中。


--------------------------------------------------------------------------------

cxcore096d.dll 或 cxcored.lib 好像丢失了
cxcore096d.dll 是 cxcore DLL 的 DEBUG 版本,cxcored.lib 是 cxcore096d.dll 的输入库。打开Open OpenCV workspace, 选择 "cxcore" 作为 active project,并且选择 "Win32 Debug" 的配置. 编译建立库,这样就得到 bin\cxcore096d.dll 和 lib\cxcored.lib。 同样步骤可以生成其它所有的 OpenCV 组件。加 d 表示 Debug 版本。


--------------------------------------------------------------------------------

当我编译 HighGUI ,得到错误 "mil.h is not found"
mil.h 是 Matrox Imaging Library (MIL) 的一个部分,提供 Matrox (或兼容) 视频采集卡,如 Meteor, Meteor II 等
If you have such a framegrabber and MIL installed, add mil\include and mil\lib to the search paths within Developer Studio (submenu Tools->Options->Directories).
If you do not have MIL, just ignore the error. The file mil.h is only required to build MIL-aware version of Highgui "Win32 MIL Debug" or "Win32 MIL Release". Select "Win32 Debug" or "Win32 Release" configuration of highgui (submenu Build->Set Active Configuration...) instead - these versions of highgui can still be used to grab video via VFW interface, work with AVIs and still images.

--------------------------------------------------------------------------------

怎样调试 DirectShow filter?

打开带 FILTER 的 workspace (e.g. opencv.dsw),
选择 filter 作为活动项目,建立 debug 配置,
注册 filter 的 debug 版本(即运行 regsvr32 camshiftd.ax) (只需要做一次就可以了,注册表里仅保存 filter 的文件名),
回到 Developer Studio 然后开始 debugging 过程 (F5). 在提示 “do you want to run to debug the module”下,选择 camshiftdemo 通过 camshift.ax 和 DirectX SDK 工具图形编辑器 graphedit 来调试 DirectShow filter.
在 graphedit 中建立 filter 图 (即 camera->camshift->renderer)
保存 graph (下次简单加载就可以了)
在filter中的变换方法或其它位置设置断点.
运行 filter ,并且。。。

--------------------------------------------------------------------------------

怎么创建一个 DeveloperStudio 项目来开始玩 OpenCV
(注意: 这是一个应用答案)

为了在 Developer Studio 下创建基于 OpenCV 的项目,按如下步骤进行:

在 Developer Studio 中创建新的应用程序:
选择菜单 "File"->"New..."->"Projects" . 选择 "Win32 Application" 或 "Win32 console application" - 后者是更简单的方法。
键入项目名称,并且选择存储位置
可以为项目创建一个单独的 workspace ("Create new workspace") , 也可以将新的项目加入到当前的 workspace 中 ("Add to current workspace").
单击 "next"
选择 "An empty project", 点击 "Finish", "OK".
经过以上步骤,Developer Studio 会创建一个项目目录 (缺省情况下,目录名就是项目名), .dsp 文件以及.dsw,.ncb ... ,如果你创建自己的workspace.
添加文件到 project 中:
选择菜单"File"->"New..."->"Files" .
选择"C++ Source File", 键入文件名,点击"OK"
增加 OpenCV 相关的 头文件目录 #include :
#include "cv.h"
/* #inlcude "cvaux.h" // experimental stuff (if need) */
#include "highgui.h"

或者你可以拷贝部分已有的文件 (如:opencv\samples\c\morphology.c) 到项目目录中,打开它,并且加入到项目中 (右键点击编辑器的视图 -> "Insert File into Project" -> ).
配置项目:
选择菜单"Project"->"Settings..."以激活项目配置对话框 .
在左边选择你的项目.
调节设置,对 Release 和 Debug 配置都有效:
选择 "Settings For:"->"All Configurations"
选择 "C/C++" tab -> "Preprocessor" category -> "Additional Include Directories:". 加入用逗号分隔的相对路径 (对文件 .dsp 而言) 或绝对路径 opencv\cxcore\include, opencv\cv\include, opencv\otherlibs\highgui 以及可选的 optionally, opencv\cvaux\include.
选择 "Link" tab -> "Input" category -> "Additional library path:". 加入输入库所在的路径 (cxcore[d].lib cv[d].lib hihghui[d].lib cvaux[d].lib)
调节 "Debug" 配置:
选择 "Settings For:"->"Win32 Debug".
选择 "Link" tab -> "General" category -> "Object/library modules". 加入空格分隔的 cvd.lib, highguid.lib, cvauxd.lib (optionally)
可以改变输出文件的名称和位置。如想把产生的 .exe 文件放置于项目目录而不是Debug/ 子目录下,可在 "Link" tab -> "General" category -> "Output file name:" 中键入 ./d.exe
调节 "Release" 配置
选择 "Settings For:"->"Win32 Release".
选择 "Link" tab -> "General" category -> "Object/library modules". 加入空格分隔的 cv.lib, highgui.lib, cvaux.lib (optionally)
增加从属性项目到 workspace 中:
选择菜单: "Project" -> "Insert project into workspace".
选择 opencv\cv\make\cv.dsp.
同样步骤对 opencv\cvaux\make\cvaux.dsp, opencv\otherlibs\highgui\highgui.dsp.
设置从属性:
选择菜单: "Project" -> "Dependencies..."
对 "cv" 选择 "cxcore",
对 "cvaux" 选择 "cv", "cxcore",
对 "highgui" 选择 "cxcore",
对你的项目,选择所有的: "cxcore", "cv", "cvaux", "highgui".
从属性配置保证了在源代码被改变的情况下,自动重新编译 opencv 库.
就这么多。可以编译并且运行一切了。

--------------------------------------------------------------------------------

Linux 的相关问题:
TODO
--------------------------------------------------------------------------------

使用库的技术问题:

--------------------------------------------------------------------------------

怎么访问图像元素
(坐标起点相对于图像原点 image origin 从 0 开始,或者是左上角 (img->origin=IPL_ORIGIN_TL) 或者是左下角 (img->origin=IPL_ORIGIN_BL)

假设有 8-bit 1-通道的图像 I (IplImage* img):
I(x,y) ~ ((uchar*)(img->imageData + img->widthStep*y))[x]

假设有 8-bit 3-通道的图像 I (IplImage* img):
I(x,y)blue ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3]
I(x,y)green ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3+1]
I(x,y)red ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3+2]

如果增加点 (100,100) 的亮度 30 ,那么可以:
CvPoint pt = {100,100};
((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3] += 30;
((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+1] += 30;
((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+2] += 30;

或者更有效的
CvPoint pt = {100,100};
uchar* temp_ptr = &((uchar*)(img->imageData + img->widthStep*pt.y))[x*3];
temp_ptr[0] += 30;
temp_ptr[1] += 30;
temp_ptr[2] += 30;

假设有 32-bit 浮点数, 1-通道 图像 I (IplImage* img):
I(x,y) ~ ((float*)(img->imageData + img->widthStep*y))[x]

现在,通用方法:假设有 N-通道,类型为 T 的图像:
I(x,y)c ~ ((T*)(img->imageData + img->widthStep*y))[x*N + c]
或者你可使用宏 CV_IMAGE_ELEM( image_header, elemtype, y, x_Nc )
I(x,y)c ~ CV_IMAGE_ELEM( img, T, y, x*N + c )

也有针对各种图像(包括 4-通道)和矩阵的函数(cvGet2D, cvSet2D), 但是它们都很慢.
--------------------------------------------------------------------------------

如何访问矩阵元素?
方法是类似的 (都是针对 0 起点的列和行)

设有 32-bit 浮点数的实数矩阵 M (CvMat* mat):
M(i,j) ~ ((float*)(mat->data.ptr + mat->step*i))[j]

设有 64-bit 浮点数的复数矩阵 M (CvMat* mat):
Re M(i,j) ~ ((double*)(mat->data.ptr + mat->step*i))[j*2]
Im M(i,j) ~ ((double*)(mat->data.ptr + mat->step*i))[j*2+1]

设有单通道矩阵,有宏 CV_MAT_ELEM( matrix, elemtype, row, col ), 例如对 32-bit 浮点数的实数矩阵
M(i,j) ~ CV_MAT_ELEM( mat, float, i, j ),
假如初始化 3x3 单位阵:
CV_MAT_ELEM( mat, float, 0, 0 ) = 1.f;
CV_MAT_ELEM( mat, float, 0, 1 ) = 0.f;
CV_MAT_ELEM( mat, float, 0, 2 ) = 0.f;
CV_MAT_ELEM( mat, float, 1, 0 ) = 0.f;
CV_MAT_ELEM( mat, float, 1, 1 ) = 1.f;
CV_MAT_ELEM( mat, float, 1, 2 ) = 0.f;
CV_MAT_ELEM( mat, float, 2, 0 ) = 0.f;
CV_MAT_ELEM( mat, float, 2, 1 ) = 0.f;
CV_MAT_ELEM( mat, float, 2, 2 ) = 1.f;


--------------------------------------------------------------------------------

如何在 OpenCV 中处理我自己的数据
设你有 300x200 32-bit 浮点数 image/array, 也就是对一个有 60000 个元素的数组.

int cols = 300, rows = 200;
float* myarr = new float[rows*cols];

// step 1) initializing CvMat header
CvMat mat = cvMat( rows, cols,
CV_32FC1, // 32-bit floating-point, single channel type
myarr // user data pointer (no data is copied)
);
// step 2) using cv functions, e.g. calculating l2 (Frobenius) norm
double norm = cvNorm( &mat, 0, CV_L2 );

...
delete myarr;

其它情况在参考手册中有描述.见 cvCreateMatHeader, cvInitMatHeader, cvCreateImageHeader, cvSetData etc.
--------------------------------------------------------------------------------

如何加载和显示图像
/* usage: prog */
#include "cv.h"
#include "highgui.h"

int main( int argc, char** argv )
{
IplImage* img;
if( argc == 2 && (img = cvLoadImage( argv[1], 1)) != 0 )
{
cvNamedWindow( "Image view", 1 );
cvShowImage( "Image view", img );
cvWaitKey(0); // very important, contains event processing loop inside
cvDestroyWindow( "Image view" );
cvReleaseImage( &img );
return 0;
}
return -1;
}



<< Home

This page is powered by Blogger. Isn't yours?