2006-08-29

View3D ---- A 3D Viewer

View3D is a 3D Viewer Degigned by me, it can realize rotation, translation, scaling, selection of a 3D model. It support obj file format, which means it can load and save 3D mesh models by obj file format.

I use halfedge mesh structure in the software, and I also realize my undergraduate thesis project "Progressive Mesh" under this software.

This Software is designed by OpenGL, anyone who want to get source can emai me :
xlvector@gmail.com

Flollowing is Screen Capture of Software View3D:



 Posted by Picasa

2006-08-21

How To Compile OpenCV in Linux

Under Linux, how to compile OpenCV with some libraries not in standard path ?

  • The solution is to use the CFLAGS, CPPFLAGS and LDFLAGS environment variables at configure time. For example, if you have ffmpeg library in one you your own directories, you can do (all on one command line):

  • ./configure CFLAGS=-I/where/is/ffmpeg/include CPPFLAGS=-I/where/is/ffmpeg/include LDFLAGS=-L/where/is/ffmpeg/lib

How to compile C samples under Linux ?

  • If OpenCV is installed in a standard path, you can quickly compile all the C samples with:

  • cd /where/you/have/the/c/samples

  • sh ./build_all.sh

    If OpenCV is not installed in a standard path, you need to setup the PKG_CONFIG_PATH variable. For example (assuming you are using a sh-based shell, like bash or zsh):

  • cd /where/you/have/the/c/samples

  • PKG_CONFIG_PATH=/where/you/have/installed/opencv/lib/pkgconfig:${PKG_CONFIG_PATH}

  • export PKG_CONFIG_PATH

  • sh ./build_all.sh

    You can check that the PKG_CONFIG_PATH is correct by doing either:

  • pkg-config --cflags opencv

  • pkg-config --libs opencv

    You must have something like:

  • $ pkg-config --cflags opencv

  • -I/where/you/have/installed/opencv/include/opencv

  • $ pkg-config --libs opencv

  • -L/com/softs/opencv-cvs/cvs-dev-i686/lib -lcxcore -lcv -lhighgui -lcvaux

How can I compile and link some OpenCV based program under Linux ?

  • The best way is to use pkg-config. Just define the correct PKG_CONFIG_PATH:

  • PKG_CONFIG_PATH=/where/you/have/installed/opencv/lib/pkgconfig:${PKG_CONFIG_PATH}

  • export PKG_CONFIG_PATH

    And then, compile your program like:

  • gcc `pkg-config --cflags opencv` `pkg-config --libs opencv` -o my-opencv-prgm my-opencv-prgm.c

    or simply:

  • gcc `pkg-config --cflags --libs opencv` -o my-opencv-prgm my-opencv-prgm.c

  • if that fails try:

  • gcc -I/home/intel/opencv/include -L/home/intel/opencv/lib -lopencv -lhighgui -lstdc++ opencv0.c -o opencv0

What if I get an error about OpenCV libraries when running a program?

If, after following the instructions above, your program compiles, but gives an error message that a library cannot be found when it is run, on Fedora systems:

  • create a file called opencv.conf in /etc/ld.so.conf.d/ which contains the path to your opencv libraries (by default /usr/local/lib).

  • become root and run ldconfig.

Or, add the location of the OpenCV libraries to your LD_LIBRARY_PATH (should work on most systems including Fedora)

2006-08-20

利用Video4Linux获取摄像头数据

Video4Linux是Linux下用于获取视频和音频数据的API接口,在这篇文章中,我着重阐述如何利用Video4Linux获取摄像头数据,以实现连续影像的播放。
1. 摄像头的安装
在Linux下常用的摄像头驱动是spca5xx, 这是一个通用驱动,读者可以在以下网站下到这个驱动 http://mxhaard.free.fr/download.html。这个网站还给出了这款驱动支持
的摄像头的种类。另外,ov511芯片直接就支持Linux,使用者款芯片的摄像头有网眼V2000。我使用的是网眼V2000的摄像头,和Z-Star 301p+现代7131R芯片的摄像头。后一
种需要spca5xx的驱动。关于spca5xx的安装方法,网上有很多介绍,这里就不说了。
2. 摄像头的调试
安装好摄像头后,为了测试摄像头能否正常工作,可以用一下软件。比较著名的是xawtv,在网上搜以下可以下载到。安装好后,打开xawtv则可以调试摄像头。
3. Video4Linux 编程获取数据。
现有的video4linux有两个版本,v4l和v4l2。本文主要是关于v4l的编程。利用v4l API获取视频图像一般有以下几步:
a> 打开设备
b> 设置设备的属性,比如图像的亮度,对比度等等
c> 设定传输格式和传输方式
d> 开始传输数据,一般是一个循环,用以连续的传输数据
e> 关闭设备
下面具体介绍v4l编程的过程。首先指出,在video4linux编程时要包含头文件,其中包含了video4linux的数据结构和函数定义。
1)v4l的数据结构
在video4linux API中定义了如下数据结构,详细的数据结构定义可以参考v4l API的文档,这里就编程中经常使用的数据结构作出说明。
首先我们定义一个描述设备的数据结构,它包含了v4l中定义的所有数据结构:
typedef struct _v4ldevice
{
int fd; //设备号
struct video_capability capability;
struct video_channel channel[10];
struct video_picture picture;
struct video_clip clip;
struct video_window window;
struct video_capture capture;
struct video_buffer buffer;
struct video_mmap mmap;
struct video_mbuf mbuf;
struct video_unit unit;
unsigned char *map; //mmap方式获取数据时,数据的首地址
pthread_mutex_t mutex;
int frame;
int framestat[2];
int overlay;
}v4ldevice;
下面解释上面这个数据结构中包含的数据结构,这些结构的定义都在中。
* struct video_capability
name[32] Canonical name for this interface
type Type of interface
channels Number of radio/tv channels if appropriate
audios Number of audio devices if appropriate
maxwidth Maximum capture width in pixels
maxheight Maximum capture height in pixels
minwidth Minimum capture width in pixels
minheight Minimum capture height in pixels
这一个数据结构是包含了摄像头的属性,name是摄像头的名字,maxwidth maxheight是摄像头所能获取的最大图像大小,用橡素作单位。
在程序中,通过ioctl函数的VIDIOCGCAP控制命令读写设备通道已获取这个结构,有关ioctl的使用,比较复杂,这里就不说了。下面列出获取这一数据结构的代码:
int v4lgetcapability(v4ldevice *vd)
{
if(ioctl(vd->fd, VIDIOCGCAP, &(vd->capability)) < 0) {
v4lperror("v4lopen:VIDIOCGCAP");
return -1;
}
return 0;
}
* struct video_picture
brightness Picture brightness
hue Picture hue (colour only)
colour Picture colour (colour only)
contrast Picture contrast
whiteness The whiteness (greyscale only)
depth The capture depth (may need to match the frame buffer depth)
palette Reports the palette that should be used for this image
这个数据结构主要定义了图像的属性,诸如亮度,对比度,等等。这一结构的获取通过ioctl发出VIDIOCGPICT控制命令获取。
* struct video_mbuf
size The number of bytes to map
frames The number of frames
offsets The offset of each frame
这个数据结构在用mmap方式获取数据时很重要:
size表示图像的大小,如果是640*480的彩色图像,size=640*480*3
frames表示帧数
offsets表示每一帧在内存中的偏移地址,通过这个值可以得到数据在图像中的地址。
得到这个结构的数据可以用ioctl的VIDIOCGMBUF命令。源码如下:
int v4lgetmbuf(v4ldevice *vd)
{
if(ioctl(vd->fd, VIDIOCGMBUF, &(vd->mbuf))<0) {
v4lperror("v4lgetmbuf:VIDIOCGMBUF");
return -1;
}
return 0;
}
而数据的地址可以有以下方式计算:
unsigned char *v4lgetaddress(v4ldevice *vd)
{
return (vd->map + vd->mbuf.offsets[vd->frame]);
}
2)获取影像mmap方式。
在video4linux下获取影像有两种方式:overlay和mmap。由于我的摄像头不支持overlay方式,所以这里只谈mmap方式。
mmap方式是通过内存映射的方式获取数据,系统调用ioctl的VIDIOCMCAPTURE后,将图像映射到内存中,
然后可以通过前面的v4lgetmbuf(vd)函数和v4lgetaddress(vd)函数获得数据的首地址,这是李可以选择是将它显示出来还是放到别的什么地方。
下面给出获取连续影像的最简单的方法(为了简化,将一些可去掉的属性操作都去掉了):
char* devicename="/dev/video0";
char* buffer;
v4ldevice device;
int width = 640;
int height = 480;
int frame = 0;
v4lopen("/dev/video0",&device); //打开设备
v4lgrabinit(&device,width,height); //初始化设备,定义获取的影像的大小
v4lmmap(&device); //内存映射
v4lgrabstart(&device,frame); //开始获取影像
while(1){
v4lsync(&device,frame); //等待传完一帧
frame = (frame+1)%2; //下一帧的frame
v4lcapture(&device,frame); //获取下一帧
buffer = (char*)v4lgetaddress(&device);//得到这一帧的地址
//buffer给出了图像的首地址,你可以选择将图像显示或保存......
//图像的大小为 width*height*3
..........................
}
为了更好的理解源码,这里给出里面的函数的实现,这里为了简化,将所有的出错处理都去掉了。
int v4lopen(char *name, v4ldevice *vd)
{
int i;
if((vd->fd = open(name,O_RDWR)) < 0) {
return -1;
}
if(v4lgetcapability(vd))
return -1;
}
int v4lgrabinit(v4ldevice *vd, int width, int height)
{
vd->mmap.width = width;
vd->mmap.height = height;
vd->mmap.format = vd->picture.palette;
vd->frame = 0;
vd->framestat[0] = 0;
vd->framestat[1] = 0;
return 0;
}
int v4lmmap(v4ldevice *vd)
{
if(v4lgetmbuf(vd)<0)
return -1;
if((vd->map = mmap(0, vd->mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, vd->fd, 0)) < 0) {
return -1;
}
return 0;
}
int v4lgrabstart(v4ldevice *vd, int frame)
{
vd->mmap.frame = frame;
if(ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) < 0) {
return -1;
}
vd->framestat[frame] = 1;
return 0;
}
int v4lsync(v4ldevice *vd, int frame)
{
if(ioctl(vd->fd, VIDIOCSYNC, &frame) < 0) {
return -1;
}
vd->framestat[frame] = 0;
return 0;
}
int c4lcapture(v4ldevice *vd, int frame)
{
vd->mmap.frame = frame;
if(ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) < 0) {
return -1;
}
vd->framestat[frame] = 1;
return 0;
}

Linux动态链接库的创建与使用

本文主要探讨Linux下动态链接库的创建与使用。
一. 创建
下面举一个例子:
/*
add.h
*/
#ifndef _ADD_H
#define _ADD_H
#ifdef SHARED
int (* addnum)(int a, int b);
#endif
#endif
/*
addnum.c
*/
#include "add.h"
#include
int addnum(int a,int b){
int c=a+b;
return c;
}
然后用gcc将这两个文件编译成动态链接库.so文件。
gcc -c add.h addnum.c
gcc -shared -o addnum.so addnum.o
这样就生成了动态链接库addnum.so文件
二. 使用动态链接库
/* main.c */
#include
#include
#define SOFILE "./addnum.so"
#define SHARED
int main(){
printf("Open Dynamic Lib!\n");
void *dp=dlopen(SOFILE,RTLD_LAZY);
int (*addnum)(int,int);
if(NULL==dp){
printf("Open Dynamic Lib Failed!\n");
return -1;
}
addnum=dlsym(dp,"addnum");
int a=10,b=20;
int c=addnum(a,b);
printf("The sum is : %d\n",c);
dlclose(dp);
return 1;
}
用如下的命令编译:
gcc main.c -ldl -o main
然后运行:
./main
结果是:
The Sum is :30
但是,如果定义成C++文件,上述方法在使用时可能会出问题,此时需要强制类型转换.
addnum=(int (*)(int,int))dlsym(dp,"addnum")

Natural Image Matting

Introduction
Composition Image I is generated by foreground and background with alpha matte

I = alpha*F + (1-alpha)*B

Matting is a problem to get alpha,F,B from a given image I.
User have to devide the image into three region: Foreground, Background and Unknown area. In foreground area, F = I, alpha = 1, B = 0; In background area, F = 0, alpha = 0, B = I. Our task is to get F,B,alpha in unknown area.
Consider a point P in unknown area, we have to first estimate F and B in point P.
After estimate F,B in point P, we estimate alpha by minimize a energy:

V = a*V(P) + b*V(P,Q) Q is 4-neighbor of P

V(P) = C - alpha*F - (1-alpha)*B^2

V(P,Q) = alpha(P) - alpha(Q)^2

Result





Reference (All can be downloaded from Google)

  • Y.Chuang, B.Curless, DH.Salesin, R.Szeliski, A Bayesian Approcah to Digital Matting.
  • J.Sun, J.Jia, CK.Tang, HY.Shum, Poisson Matting.
  • A.Levin, D.Lischinski, Y.Weiss, A Closed Form Solution to Natural Image Matting.
  • J.Wang, MF.Cohen, An Iterative Optimization for Unified Image Segmentation and Matting.

Progressive Mesh Algorithm based on HalfEdge Mesh Structure

这是我的本科毕业论文,嘿嘿!

Abstract:
When storing, rendering, transmitting highly detailed mesh models, we may meet difficulty like slow speed or poor quality. In order to solve these problems, Hoppe introduced Progressive Mesh(PM) Representation, and this method has broad application in Mesh Simplification, Level-of-detail, Progressive Transmission, Mesh Compression, and so on. In this thesis, I realize PM algorithm in HalfEdge Mesh structure. Compared with general mesh structure, halfedge structure can improve many algorithms' arithmetic speed, and it's easy to obtain mesh topological structure by using halfedge mesh structure. This thesis consists of five parts. First, the background of PM will be given. Next, an interactive computer graphics platform which supports rotation, scaling, translation, selection will be introduced. 3D objects' mesh representation will be discussed in third part. In the fourth part, PM algorithm will be explained in detail. Discussion is the final of this thesis.

Result:
These are a part of results of undergraduate thesis, mainly use Progressive Mesh Algorithm to do Mesh Simplification.