环境:
Ubuntu10.04
OK6410开发板
ARM Linux3.01系统
QT4.7.1
OpenCV-2.0.0
arm-linux-g++ 4.3.2 / arm-linux-gcc 4.3.2
CMake-gui 2.8.0
OpenCV2.0.0交叉编译过程:
1、在usr/local新建文件夹
# mkdir opencv
把下载的OpenCV-2.0.0.tar.bz2解压到 usr/local/opencv 目录下
2、然后在usr/local/opencv 新建一个 opencv-arm 文件夹,作为CMake编译arm版本的工作目录
# mkdir opencv-arm
如下图所示:
3、在终端里调出CMake gui界面:
# cmake-gui
按照下图方式选择源码目录和build目录
然后点击Configure按钮,保持generator为Unix Makefiles,选择Specify options for cross-compiling,点击Next
按照如下方式配置:
注:/usr/local/arm/4.3.2 为交叉编译工具 arm-linux-g++/gcc 的所在包含文件夹(在bin文件夹里面)
然后点击 “Finish” 按钮;
修改默认配置,默认安装目录为/usr/local,但我想对它统一归类,所以我在/usr/local/arm/4.3.2/lib目录下新建了一个opencv文件夹,在Cmake-gui里修改CMAKE_INSTALL_PREFIX变量改为/usr/local/arm/4.3.2/lib/opencv/
(另外,如果没有安装tiff图像的支持,请去掉WITH_TIFF)
然后点击Generate按钮生成Makefile;
4、在终端界面中,进入目录/usr/local/opencv/opencv-arm,运行make编译opencv
编译时发现如下错误:
Linking CXX executable ../../bin/opencv_createsamples
../../lib/libcxcore.so: undefined reference to `clock_gettime'
../../lib/libcxcore.so: undefined reference to `pthread_key_create'
../../lib/libcxcore.so: undefined reference to `pthread_getspecific'
../../lib/libcxcore.so: undefined reference to `pthread_setspecific'
原因是cmake不认识我定义的arm-linux系统标记,没有加上库pthread和rt的链接选项
此时需要修改CMakeCache.txt,CMAKE_EXE_LINKER_FLAGS原来为空,加上-lpthread -lrt,如下图:
重新make编译,错误消除,编译成功之后的界面如下:
5、然后运行make install,将opencv生成的库和头文件安装到目录/usr/local/arm/4.3.2/lib/opencv/,结果如下:
6、把这5个 .so 库文件拷贝到ARM板系统中的 /lib 目录下面:(如下是添加之后的截图)
void Widget::paintEvent(QPaintEvent *)
{
uchar * pImgBuf;
unsigned int len;
camReturn = m_camera->get_frame((void **)&pImgBuf,&len);
convert_yuv_to_rgb_buffer(pImgBuf,imgBuf,image_width,image_height);
frame->loadFromData((uchar *)imgBuf,/*len*/image_width * image_height * 3 * sizeof(char));
IplImage* src = QImageToIplImage(frame);
if (!src)
{
printf("img error!");
return;
}
//更改图像大小(后期对人脸检测时间控制会有很大帮助)
double sizeScale = imgSizeScaleSmall;
CvSize img_cvsize;
img_cvsize.width = src->width * sizeScale;
img_cvsize.height = src->height * sizeScale;
IplImage* dst = cvCreateImage(img_cvsize, src->depth, src->nChannels);
cvResize(src, dst, CV_INTER_LINEAR); //opencv函数更改图片大小
// cvSaveImage("jason.jpg", src); //ARM对opencv的highgui支持极其差,这个函数不能使用
//更改图像大小,清晰度会下降
sizeScale = imgSizeScaleBig;
img_cvsize.width = dst->width * sizeScale;
img_cvsize.height = dst->height * sizeScale;
IplImage* img = cvCreateImage(img_cvsize, dst->depth, dst->nChannels);
cvResize(dst, img, CV_INTER_LINEAR);
QImage qimage = QImage((uchar *)img->imageData, img->width,img->height, image_Format);
//IplImage为BGR格式,QImage为RGB格式,所以要交换B和R通道显示才正常
//可以用OpenCV的cvConcertImage函数交换,也可以用QImage的rgbSwapped函数交换;
qimage = qimage.rgbSwapped();
ui->m_imgLabel->setPixmap(QPixmap::fromImage(qimage));
camReturn = m_camera->unget_frame();
cvReleaseImage(&img); //释放图片内存
cvReleaseImage(&src);
}
IplImage* Widget::QImageToIplImage(const QImage * qImage)
{
int width = qImage->width();
int height = qImage->height();
CvSize Size;
Size.height = height;
Size.width = width;
IplImage *IplImageBuffer = cvCreateImage(Size, IPL_DEPTH_8U, 3);
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
QRgb rgb = qImage->pixel(x, y);
cvSet2D(IplImageBuffer, y, x, CV_RGB(qRed(rgb), qGreen(rgb), qBlue(rgb)));
}
}
return IplImageBuffer;
}