存档在 ‘OpenCv’ 分类

Linux下OpenCv+Qt搭配使用问题

2016年5月4日

发现一个奇怪的现象,OpenCv代码在直接使用g++或者cmake+make编译后代码能正常跑出效果,但是以Qt组织工程后,任何涉及到OpenCv的代码都导致程序崩溃,比如segment error(段错误),relloc error或者the inferior has stopped because receive a signal的错误,经过多次实验排查,定位到问题。

现象:
使用原生的g++编译没问题

g++  -ggdb `pkg-config --cflags opencv` main.cpp -o main `pkg-config --libs opencv`  

使用Cmake没问题,CMakeLists.txt内容如下:

######## A simple cmakelists.txt file for OpenCV() #############
cmake_minimum_required(VERSION 2.8)
PROJECT(ShowImage)
FIND_PACKAGE( OpenCV REQUIRED )   
INCLUDE_DIRECTORIES( 
  ${ShowImage_SOURCE_DIR}
)
ADD_EXECUTABLE(ShowImage main.cpp)  
TARGET_LINK_LIBRARIES (ShowImage ${OpenCV_LIBS} )
cmake .
make

在QtCreator中,配置文件中加有

INCLUDEPATH+=/usr/local/include\
/usr/local/include/opencv\
/usr/local/include/opencv2
LIBS+=/usr/local/lib/libopencv_highgui.so\
/usr/local/lib/libopencv_core.so\
/usr/local/lib/libopencv_imgproc.so\
/usr/local/lib/libopencv_imgcodecs.so \
/usr/local/lib/libopencv_superres.so \
/usr/local/lib/libopencv_videoio.so \
/usr/local/lib/libopencv_calib3d.so \
/usr/local/lib/libopencv_video.so \
/usr/local/lib/libopencv_features2d.so \
/usr/local/lib/libopencv_videostab.so \
/usr/local/lib/libopencv_flann.so \
/usr/local/lib/libopencv_highgui.so \
/usr/local/lib/libopencv_imgcodecs.so \
/usr/local/lib/libopencv_imgproc.so \
/usr/local/lib/libopencv_ml.so \
/usr/local/lib/libopencv_objdetect.so 

但是程序总是停止运行。

解决办法:
首先

qmake -v
QMake version 2.01a
Using Qt version 4.8.6 in /usr/lib/x86_64-linux-gnu

可以看出当前该系统安装的Qt版本。在编译OpenCv时带的参数WITH_QT=ON选项会导致OpenCv编译时使用qt4,应该是这种关联导致冲突或者不匹配。
你现在可以这样做:

cd build
make uninstall
make clean
cd ..
rm -rf build

即卸载,清除,删除文件夹,现在只需要将opencv重新编译一遍即可,注意去掉WITH_QT=ON选项。

ubuntu下opencv2.4.9/3.0/3.1安装过程

2016年5月3日

安装OpenCv后出现各种问题,究其原因是一些基础库没有安装好,以下是基础库安装步骤,保证尽量完整,免得在使用的时候出错。

  • 1.由于opencv的cmakelist里依赖一些库,所有要先配置好这些库,先去除你电脑上的这些重新装.
  •  apt-get remove ffmpeg x264 libx264-dev
  • 2.安装其他依赖库.
  •  apt-get update
     apt-get install build-essential checkinstall Git cmake libfaac-dev libjack-jackd2-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libsdl1.2-dev libtheora-dev libva-dev libvdpau-dev libvorbis-dev libx11-dev libxfixes-dev libxvidcore-dev texi2html yasm zlib1g-dev
  • 3.安装gstreamer,主要是opencv里头的相机模块用到
  •   apt-get install libgstreamer0.10-0 libgstreamer0.10-dev gstreamer0.10-tools gstreamer0.10-plugins-base libgstreamer-plugins-base0.10-dev gstreamer0.10-plugins-good gstreamer0.10-plugins-ugly gstreamer0.10-plugins-bad gstreamer0.10-ffmpeg

    如果 gstreamer0.10-ffmpeg提示没有候选,那么手动下载并安装,或者按如下步骤安装

     apt-get install libgstreamer0.10-dev gstreamer-tools gstreamer0.10-tools gstreamer0.10-doc
    apt-get install gstreamer0.10-plugins-base gstreamer0.10-plugins-good gstreamer0.10-plugins-ugly gstreamer0.10-plugins-bad gstreamer0.10-plugins-bad-multiverse  

    所有您需要做的就是添加PPA到您的系统,更新本地存储索引和安装gstreamero.10-ffmpeg包。如下输入命令:

     add-apt-repository ppa:mc3man/trusty-media
    apt-get update
    apt-get install gstreamer0.10-ffmpeg
  • 4.安装gtk,jpeg8
  •  apt-get install libgtk2.0-0 libgtk2.0-dev
    apt-get install libjpeg8 libjpeg8-dev
  • 5.安装 install x264.
  • 下载链接: ftp://ftp.videolan.org/pub/videolan/x264/snapshots

     tar xvf x264-snapshot-**********-stable.tar.bz2
    cd x264-snapshot--**********--stable
    ./configure --enable-shared --enable-pic
    make
     make install

    由于我的电脑是64位,所以要加上 –enable-shared –enable-pic ,否则就会报错:

        /usr/bin/ld: /usr/local/lib/libavcodec.a(avpacket.o): relocation R_X86_64_32S against `av_destruct_packet' can not be used when making a shared object; recompile with -fPIC
        /usr/local/lib/libavcodec.a: could not read symbols: Bad value
  • 6.安装ffmpeg
  • 如果出现下面错误:

     /usr/local/lib/libswscale.a(swscale_unscaled.o): relocation R_X86_64_32S against `av_pix_fmt_descriptors@@LIBAVUTIL_52' can not be used when making a shared object; recompile with -fPIC
    /usr/local/lib/libswscale.a: error adding symbols: 错误的值
    collect2: error: ld returned 1 exit status
    make[2]: *** [lib/libopencv_highgui.so.2.4.9] 错误 1
    make[1]: *** [modules/highgui/CMakeFiles/opencv_highgui.dir/all] 错误 2
    make: *** [all] 错误 2

    可能是opencv249依赖的ffmpeg版本不对照

     wget http://ffmpeg.org/releases/ffmpeg-1.2.tar.bz2
    tar xvf ffmpeg-1.2.tar.bz2
    cd ffmpeg-1.2
    ./configure --enable-gpl --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-nonfree --enable-postproc --enable-version3 --enable-x11grab --enable-shared --enable-pic
    make
    make install
  • 7.安装v4l (video for linux) , http://www.linuxtv.org/downloads/v4l-utils/.
  • 报错:dvb-v5.h:69:9: error: ‘NULL’ undeclared here ……..原因是v4l的版本不对,于是我装了v4l 1.0.0

     wget http://www.linuxtv.org/downloads/v4l-utils/v4l-utils-1.0.0.tar.bz2
    tar xvf v4l-utils-1.0.0.tar.bz2
    cd v4l-utils1.0.0
    make
    make install
  • 8.安装OpenCV 2.4.9.
  •  tar xvf OpenCV-2.4.9.tar.bz2
    cd OpenCV-2.4.9/
    mkdir build
    cd build
    cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D WITH_V4L=ON  -D WITH_OPENGL=ON ..
    make
    make install

    -D WITH_QT=ON选项就别加上了,免得在Qt中用不了
    环境变量中添加

     export LD_LIBRARY_PATH=/usr/local/lib

    另外修改

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

    追加 /usr/local/lib
    执行

     sudo ldconfig /etc/ld.so.conf

    在/etc/bash.bashrc添加

     PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
    export PKG_CONFIG_PATH

    最后查看版本和头文件目录

     pkg-config --modversion opencv
    pkg-config --cflags opencv 

如果准备在Qt Creator中写代码,关注下一篇文章:Linux下OpenCv+Qt搭配使用问题

/usr/bin/ld: cannot find -lippicv

2016年5月2日

opencv会默认安装在/usr/local/目录文件下,若要改变安装位置有选项“-D CMAKE_INSTALL_PREFIX=/usr/local”,修改后面的参数即可。
其中命令”cmake -DINSTALL_CREATE_DISTRIB=ON”是必须要加上的,否则编译以后目标文件链接库的时候会出现以下错误

/usr/bin/ld: cannot find -lippicv
collect2: error: ld returned 1 exit status

Cmake管理OpenCv工程

2016年4月12日

CMake是一款工程管理软件,比Makefile平台迁移性更好,通过CMake能自动生成Makefile。

如下是在OpenCv工程常用的CmakeLists.txt文件:

CmakeLists.txt
######## A simple cmakelists.txt file for OpenCV() #############
cmake_minimum_required(VERSION 2.8)
PROJECT(ShowImage) 
 
FIND_PACKAGE( OpenCV REQUIRED )   
INCLUDE_DIRECTORIES(                        #包含目录
  ${ShowImage_SOURCE_DIR} 
)

ADD_EXECUTABLE(ShowImage ShowImage.cpp)  
TARGET_LINK_LIBRARIES (ShowImage ${OpenCV_LIBS} )   #这两行的次序也不能变!
# ########## end ####################################

上面示例文件中, 为了使添加的两行查找OpenCV库的指令正常工作,需要如下操作:
1). 添加系统变量: OpenCV_DIR = d:\OpenCV2.3\bulid\ (cmake使用此变量获得OpenCV的安装位置.)
2). 在OpenCV_DIR下存在配置文件 OpenCVConfig.cmake.
( 缺省安装中只有OpenCVConfig.cmake.in文件, 当使用cmake编译OpenCV后,
会根据上述的.cmake.in文件产生对应的 OpenCVConfig.cmake文件.)
3). 检查 OpenCVConfig.cmake 中的路径变量是否正确, 并做修改后保存.
与INCLUDE路径相关的变量: OpenCV_INCLUDE_DIRS
与LIB路径相关的变量: OpenCV_LIB_DIR

opencv中Mat转置抽取

2014年10月15日

第一个为就地转置,第二个将转置后的结果存放于dst

template<typename T> static void
transposeI_( Mat& mat )
{
    int rows = mat.rows, cols = mat.cols;
    uchar* data = mat.data;
    size_t step = mat.step;

    for( int i = 0; i < rows; i++ )
    {
        T* row = (T*)(data + step*i);
        uchar* data1 = data + i*sizeof(T);
        for( int j = i+1; j < cols; j++ )
            std::swap( row[j], *(T*)(data1 + step*j) );
    }
}

template<typename T> static void
transpose_( const Mat& src, Mat& dst )
{
    int rows = dst.rows, cols = dst.cols;
    uchar* data = src.data;
    size_t step = src.step;

    for( int i = 0; i < rows; i++ )
    {
        T* row = (T*)(dst.data + dst.step*i);
        uchar* data1 = data + i*sizeof(T);
        for( int j = 0; j < cols; j++ )
            row[j] = *(T*)(data1 + step*j);
    }
}

opecv算法移植有感

2014年10月5日

昨天把应该用到的算法用C语言重写了一次,总的来说,难度还是比较大,并不是说算法实现如何复杂,而是你必须短时间内从对opencv一无所知到深入了解部分模块。就我个人感觉项目上的图像算法不难,好像有腐蚀、膨胀、临近插值缩放、二次线性插值缩放、msrcr、boxfilter等等。

今天花了一下午从opencv2.0中提取并改编了jpeg图像解码并储存到CvMat(也被提取出来的数据结构)中,晚上对提取出来的源代码细致的读了一次,一来熟悉算法与软件结构,二来检查错误,测试后图像编码没问题,内存暂时没问题(读取10万张图片进来处理,并没发现内存相关问题)。

现在可以终于脱离opencv来跑算法了,但是图像解码那块还是C++写的,还需要花时间用C语言重构,但是难度瞬间降低了。

» 阅读更多: opecv算法移植有感

AutoBuffer类

2014年10月4日

如果申请的内存小于fixed_size,则直接使用_Tp buf[fixed_size],否则重新分配更多字节。

template<typename _Tp, size_t fixed_size=4096/sizeof(_Tp)+8> class CV_EXPORTS AutoBuffer
{
public:
    typedef _Tp value_type;

    AutoBuffer();
    AutoBuffer(size_t _size);
    ~AutoBuffer();

    void allocate(size_t _size);
    void deallocate();
    operator _Tp* ();
    operator const _Tp* () const;

protected:
    _Tp* ptr;
    size_t size;
    _Tp buf[fixed_size];
};


template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer()
: ptr(buf), size(fixed_size) {}

template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size)
: ptr(buf), size(fixed_size) { allocate(_size); }

template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::~AutoBuffer()
{ deallocate(); }

template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::allocate(size_t _size)
{
    if(_size <= size)
        return;
    deallocate();
    if(_size > fixed_size)
    {
        ptr = cv::allocate<_Tp>(_size);
        size = _size;
    }
}

template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::deallocate()
{
    if( ptr != buf )
    {
        cv::deallocate<_Tp>(ptr, size);
        ptr = buf;
        size = fixed_size;
    }
}

template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator _Tp* ()
{ return ptr; }

template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const
{ return ptr; }

OpenCV单通道三通道

2014年10月2日

单通道: 此通道上值为0-255。 (255为白色,0是黑色) 只能表示灰度,不能表示彩色。
三通道,在BGR (255,255,255为白色, 0,0,0是黑色 ) 可以表示彩色, 灰度也是彩色的一种。

cv::imread函数。
screen图片是一张彩色图: cv::Mat mat = cv::imread(“/root/Desktop/photos/screen.png”); mat是三通道的,mat可以表示彩色。
screen图片是一张彩色图 cv::Mat mat = cv::imread(“/root/Desktop/photos/screen.png”,CV_LOAD_IMAGE_GRAYSCALE); mat是单通道的,mat只能表示灰色。

screen图片是一张灰色图: cv::Mat mat = cv::imread(“/root/Desktop/photos/screen.png”,CV_LOAD_IMAGE_GRAYSCALE); mat是单通道,mat只能表示灰色。
screen图片是一张灰色图: cv::Mat mat = cv::imread(“/root/Desktop/photos/screen.png”); mat是三通道,mat可以表示彩色。虽然图片显示出来是灰色,但是也是由BGR表示出来的。

单通道与三通道之间的转换:
1. 上面的imread其实也可以看作是一种转换。。(目前我用的就是这个)
接下来这两个方法,还没实践过,先记录下来,只作参考:

2.把单通道图像转成三通道图像。方法如下:

    IplImage* cannyImg = cvCreateImage(cvGetSize(gray_img),IPL_DEPTH_8U,1);//cannyImag是单通道图  
    IplImage* canny_Img = cvCreateImage(cvSize(cannyImg->width,cannyImg->height), IPL_DEPTH_8U, 3);//canny_Imag是3通道图  
    cvCvtColor(cannyImg, canny_Img, CV_GRAY2BGR);//进行变换  

3.split 分割通道,merge 合并通道。
cv::cvtColor颜色空间转换,估摸这个是重点,要用到再好好研究,现在记录在此。

备注:
cv::Mat mat = cv::imread(“/root/Desktop/photos/screen.png”);
cv::Mat_ mat_8 = mat.clone(); // mat是三通道,mat_8是单通道,直接克隆过来的后果就是。。 从彩色变成灰色,长度是原来的3倍,高度一样。 screen如果是灰色图也是一样的。

cv::Mat mat = cv::imread(“/root/Desktop/photos/screen.png”,CV_LOAD_IMAGE_GRAYSCALE);
cv::Mat_ mat_24 = mat.clone(); // mat是单通道,mat_24是三通道。 这样子clone运行会出错,还是得老老实实用上面的cvtColor.

转载自:http://blog.csdn.net/a576323437/article/details/9148627