Linux-Android-Opencv-问题记录

1.Q:When I try to install the Android Developer Tool, I get the following error.


Software being installed: Android Development Tools 11.0.0.v201105251008-128486 (com.android.ide.eclipse.adt.feature.group 11.0.0.v201105251008-128486) Missing requirement: Android Development Tools 11.0.0.v201105251008-128486 (com.android.ide.eclipse.adt.feature.group 11.0.0.v201105251008-128486) requires 'org.eclipse.wst.sse.core 0.0.0' but it could not be found

I also found that adding the WST package does not help. I get the following,

Cannot complete the install because one or more required items could not be found. Software being installed: Google Web Toolkit SDK 2.3.0 2.3.0.r37v201106211634 (com.google.gwt.eclipse.sdkbundle.e37.feature.feature.group 2.3.0.r37v201106211634) Missing requirement: Google Plugin for Eclipse 3.7 2.3.2.r37v201106211634 (com.google.gdt.eclipse.suite.e37.feature.feature.group 2.3.2.r37v201106211634) requires 'org.eclipse.wst.xml.core 0.0.0' but it could not be found Cannot satisfy dependency: From: Google Web Toolkit SDK 2.3.0 2.3.0.r37v201106211634 (com.google.gwt.eclipse.sdkbundle.e37.feature.feature.group 2.3.0.r37v201106211634) To: com.google.gdt.eclipse.suite.e37.feature.feature.group 2.3.2

I'm running Eclipse Indigo 64bit version. Could someone point me in the right direction? Or tell me where to find that missing package.


A: http://stackoverflow.com/questions/6482268/eclipse-indigo-cannot-install-android-adt-plugin


2. YV12是什么?

用videoCapture和IAMStreamConfig拿到的支持的格式列表。
发现支持2中图像格式,YV12和NV12。
具体是怎么样的内存分布不知道。查了些文档。自己修改了几个图。看出了点端倪
YV12
先看看 http://www.fourcc.org/yuv.php 上比较标准的定义:

YV12

This is the format of choice for many software MPEG codecs. It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes.


Horizontal Vertical
Y Sample Period 1 1
V Sample Period 2 2
U Sample Period 2 2

Linux-Android-Opencv-问题记录_第1张图片 Linux-Android-Opencv-问题记录_第2张图片 Linux-Android-Opencv-问题记录_第3张图片

Positive biHeight implies top-down image (top line first)

这种图片其实不是很清楚的, 搞了一个非常明白的


Linux-Android-Opencv-问题记录_第4张图片
这个wiki上面的图片示例非常明了,第一个图标识了图片真正像素的表示。
可 以看到Y1, Y2, Y7, Y8这些物理上相近的4个像素公用了同样的U1和V1,相似的Y3,Y4,Y9,Y10用的就是U2和V2。这里不同的颜色把这个特性刻画的非常形象,一 目了然。Impressive!!一直觉得教育,或者说基础的教育一定要以这样的模式来阐述这样才能知其所以然,那种盲目的抄了一本国外的教材或者合并了 几本破书的教材不是教人是毁人。 说远了,言归正传。之前说的是物理像素的表示,在内存中的分布则是一个数组,顺序就是YUV。所以如果知道所要表现的取悦的大小的话很容易查找到具体的YUV在数组中的位置。

NV12
NV12和YV12稍有不同,区别就在UV的位置。再看一张图就很明了了!

在YV12中U和V都是连续排布的,而在NV12中,U和V就交错排布的。看到内存中的排布很清楚,先开始都是Y,之后的都是U1V1U2V2的交错式排布。对于像素的压缩的效果是一样的。但是可能是硬件加速的支持与否。

3. Linux 下编译安装OpenCV

Cmake的安装

OpenCV 2.2以后版本需要使用Cmake生成makefile文件,因此需要先安装cmake。

ubuntu下安装cmake比较简单,

apt-get install cmake

如果觉得自带的版本不符合要求,可以下载安装包。

下载最新版的安装包:

http://www.cmake.org/cmake/resources/software.html

这里下载已经编译好的,这样只需要解压至需要的目录下即可使用:

tar zxvf cmake-2.8.10.2-Linux-i386.tar.gz –C /usr/local/

设置环境变量:

sudo gedit /home/emouse/.bashrc

在打开的文件后添加:

export PATH=$PATH:/usr/local/cmake-2.8.10.2-Linux-i386/bin

查看版本,测试是否安装成功:

root@emouse:/home# cmake --version 
cmake version 2.8.10.2

Ubuntu 下安装 OpenCV

软件环境:

Ubuntu 12.04

OpenCV 2.4.3

Cmake 2.8.10.1

gcc 4.6.3 (系统默认)

 

4.opencv读取视频帧数有问题

1、先安装 libgtk2.0-dev 和 pkg-config,,否则后期编译运行程序会出现类似如下的问题:

OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script) in cvNamedWindow, file /usr/local/opencv/OpenCV-2.0.0/src/highgui/window.cpp, line 100 
terminate called after throwing an instance of 'cv::Exception'

通过网络获取安装:

# apt-get install libgtk2.0-dev # apt-get install pkg-config

 

2、下载OpenCV ,文件名:OpenCV-2.4.3.tar.bz2,下载地址:

http://www.opencv.org.cn/index.php/Download

解压:

#tar jxvf OpenCV-2.4.3.tar.bz2

得到文件夹 OpenCV-2.4.3

这里新建一个文件夹OpenCV-x86作为PC编译目录。

 

3、#cmake-gui 打开cmake的gui界面,开始进行配置。

cmake主要用于进行一些配置设定,从而生成用于编译安装的makefile文件,通过界面进行参数的配置和设定,非常直观、方便。在配置中指定源码和编译目录以及生成方式。

按照下图的步骤进行配置:

Linux-Android-Opencv-问题记录_第5张图片


点击Finish后cmake即载入默认配置,如下图所示:

如图所示,窗口的中间部分即配置列表,这里和使用cmake命令直接生成makefile文件一致的,如

$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/home/OpenCV

只是这里通过图形界面的方式来进行配置,更加直观方便。

这里指对一个地方进行修改,CMAKE_BUILD_TYPE 值输入RELEASE,其他保持不变,图中蓝色虚线部分显示了默认的安装目录,生成makefile文件最后执行 make install时就会安装到这个目录,这里可以根据个人需求更改。在这里的配置中我勾选了WITH_QT 去掉了WITH_TIFF,其他更多的配置也不清楚,OpenCV中文网站也没找到系统的说明,这里暂时不深究,点击Generate生成配置文件。

进入OpenCV-x86目录可以查看Makefile文件,可以留意文件的生成时间是否和刚才的生成时间一致。

4、接下来在OpenCV-x86 分别执行make和make install即可完成编译安装。

5、安装完成后需要对系统相关环境变量进行配置:

sudo gedit /etc/ld.so.conf.d/opencv.conf

将以下内容添加到最后:

/usr/local/lib

接下来配置库:

sudo ldconfig

更改环境变量:

sudo gedit /etc/bash.bashrc

在文件后添加:

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig export PKG_CONFIG_PATH
保存退出,在运行下面的例程之前,需要重新开启终端来使配置生效。

例程测试

拷贝步骤2中解压的的/OpenCV-2.4.3/samples/c 将c文件夹拷贝出来,下面运行一下这里面的一个例程,初步体验下OpenCV。拷贝完成后进入这个文件夹:

chmod +x build_all.sh

./build_all.sh

这样就对例程目录下的源文件进行了编译,这里运行一个人脸检测的程序,下面摘录自本文参考资料3。

Some of the training data for object detection is stored in /usr/local/share/opencv/haarcascades. You need to tell OpenCV which training data to use. I will use one of the frontal face detectors available. Let’s find a face:

终端中运行:

./facedetect --cascade="/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" --scale=1.5 lena.jpg

得到的结果如下图:


到这里基本的就写完了,OpenCV我之前也没有任何基础,这里只是把平台配置起来跑通,后续的工作还有很多,欢迎各位参考。转载请注明http://emouse.cnblogs.com/

本文相关及推荐参考:

【1】http://www.samontab.com/web/2010/04/installing-opencv-2-1-in-ubuntu/

【2】http://blog.csdn.net/jasonque/article/details/8267983

【3】http://www.rosoo.net/a/201203/15774.html



以前在opencv2.0里面用到cvSetCaptureProperty函数的时候总是发生定位不准确的问题,明明是让其跳到100帧,结果却总不是100帧,定位一段连续的视频,总是出现跳跃的现象。同样的代码在opencv1.0里面完全没错。可是这是为什么?这个问题一直困扰了我半年,终于在今天知道原因了。

经过差不多一晚上的探究,得出粗略的结论。原因在于opencv2.0以后,采用ffmpeg采集视频,而在opencv1.0采用vfw采集视频(具体的概念暂时还不清楚,有时间继续补上)。而opencv在定位时候,调用的ffmpeg的av_seek_frame()函数,此函数原型为:

int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags);

其中,最后一个参数有

AVSEEK_FLAG_BACKWARD = 1; ///< seek backward
AVSEEK_FLAG_BYTE     = 2; ///< seeking based on position in bytes
AVSEEK_FLAG_ANY      = 4; ///< seek to any frame, even non key-frames

ffmpeg默认的是选取关键帧(这个概念需要具体定义)。opencv里面这个函数的参数flag是0,

int ret = av_seek_frame(ic, video_stream, timestamp, 0);

也就是按照默认的读取关键帧。因此,视频跳跃就出现了。

解决这个问题需要将0改为 AVSEEK_FLAG_ANY ,即:

int ret = av_seek_frame(ic, video_stream, timestamp, AVSEEK_FLAG_ANY );

之后重新编译opencv库,就可以了。 

P.S:测试的代码

  1. #include "opencv/highgui.h" 
  2. #include <iostream>  
  3. using namespace std;  
  4. int main( int argc, char** argv )  
  5. {   
  6.     cvNamedWindow( "Example2", CV_WINDOW_AUTOSIZE );  
  7.     CvCapture* capture = cvCreateFileCapture( "d://11.avi" );  
  8.     IplImage* frame;  
  9.     int pos=0;  
  10.     int pos1=0;  
  11.     while(1)  
  12.     {  
  13.         cvSetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES,pos);  
  14.         cout<<pos;  
  15.         frame = cvQueryFrame(capture);  
  16.         pos1=cvGetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES);  
  17.         cout<<"/t"<<pos1<<endl;  
  18.         if( !frame ) break;  
  19.         cvShowImage( "Example2", frame );  
  20.         char c = cvWaitKey(33);  
  21.         if( c == 27 ) break;  
  22.         pos++;  
  23.     }  
  24.     cvReleaseCapture( &capture );  
  25.     cvDestroyWindow( "Example2" );  


使用Python 调用c/c++

为什么要调用C/C++函数

1. 性能

        Python具有编程效率高、丰富的库、活跃的社区等优点,性能虽然比Ruby等动态脚本语言更高,但还是比C/C++等老牌高性能语言差不少,在一些需要高性能的地方(比如加/解密算法)还是有所欠缺,此时就需要借助C/C++生成库,由python调用。

2. 安全

        产品要开放一些接口给开发者或则其它部门同事调用,但是接口实现不能暴露给对方,如果对方使用python,则可以用C/C++封装接口的实现生成lib提供给他们。

如何调用C函数

        Python调用C函数的实现比较简单。C语言端不需要增加任何多余的适配python的代码,直接生成so库就可以了。Python端只需要importctypes的库,直接调用so就可以了。
        首先我们用C语言实现一个加法运算,以下是test.c的代码

#include < stdio.h >

int add(int n, int m)
{
    return (n+m);
}

        然后将上述代码编译成一个动态库test.so

gcc -c -fPIC test.c
gcc -shared test.o -o test.so

        最后,python便可以按照如下方式调用test.so

>>> from ctypes import *
>>> import os
>>> test = cdll.LoadLibrary(os.getcwd() + "/test.so")
>>> print test.add(3,7)
10

        如果test.so不在python执行的当前路径下,则需要将LoadLibrary参数改为test.so所在路径。

如何调用C++函数

        Python调用C++函数比调用C函数相对要复杂些,这是因为C++编译时生成的符号表不是直接和代码中的对象名称完全相同的,因此需要在C++代码中增加相应的python适配代码,便于python查找对应的符号。为了叙述方便,比较更明了直接,本文以一个伪C++代码(没有使用类,功能部分与上述C代码完全一致)来说明使用方法
        C++端的适配代码一般需要如下几个步骤

  1. 包含Python.h头文件
  2. 这需要系统安装了python-devel库,否则无法找到Python.h头文件。

  3. 实现功能
  4. 和正常编写C++代码一样,比如要实现一个add功能的函数,代码如下

    int add(int n, int m)
    {
        return (n+m);
    }
    
  5. 编写Python代码会调用的函数,一般命名为libname_funcname,本例子中该函数命名为test_add;
  6. 这个函数一般包含两个参数:self和args.
            self参数指向模块对象;
            args参数指向python元组对象,这个元组的每个元素对应C++语言中的参数,PyArg_ParseTuple()函数检查python的参数列表并且将其转换为对应C++的值,如果转换不成功,则会返回false;

    PyObject *
    test_add(PyObject * self, PyObject * args)
    {
      int n, m, result;
    
      if (!PyArg_ParseTuple (args, "ii", &n, &m)) // 把python的变量转换成c的变量
        return NULL;
      result = add(n, m);
      return Py_BuildValue ("i", result); // //把c的返回值转换成python的对象 
    }
    
  7. 实现方法列表
  8. 方法列表中的每项由四个部分组成:方法名、导出函数、参数传递方式和方法描述。方法名是从Python解释器中调用该方法时所使用的名字。参数传递方式则规定了Python向C函数传递参数的具体形式,可选的两种方式是METH_VARARGS和METH_KEYWORDS,其中METH_VARARGS是参数传递的标准形式,它通过Python的元组在Python解释器和C函数之间传递参数,若采用METH_KEYWORD方式,则Python解释器和C函数之间将通过Python的字典类型在两者之间进行参数传递。

    static PyMethodDef testMethods[] = {
        {"add", wrap_add, METH_VARARGS, "add..."},
        {NULL, NULL, 0, NULL}
    };
    
  9. 初始化函数
  10. 所有的Python扩展模块都必须要有一个初始化函数,以便Python解释器能够对模块进行正确的初始化。Python解释器规定所有的初始化函数的函数名都必须以init开头,并加上模块的名字;

    PyMODINIT_FUNC inittest(void)
    {
        (void) Py_InitModule("test", testMethods);
    }
    

然后将上述代码编译成一个动态库test.so

g++ -fPIC -c -I /usr/include/python2.6/  test.cpp 
g++ -shared test.o -o test.so

        于是python便可以按如下方式调用c++的so

>>> import sys
>>> sys.path.append("/home/src/python/example")
>>> import test
>>> test.add(3,9)
12
>>> 

See also

  1. ExtendingPython with C or C++
  2. Python调用C/C++函数
    zzfrom: http://giftbrandmaker.com/myblog/?p=315

用c写一个python的module, 突然出现以下警告,

warning: "_POSIX_C_SOURCE" redefined

虽然程序可以运行,但看到警告心里面总是不爽。后来搜索发现,只要把#include <Python.h>放到代码的最上面,让它先加载python头文件,然后才是,

 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #include <stdbool.h>
 15 #include <string.h>

就OK。




你可能感兴趣的:(Linux-Android-Opencv-问题记录)