一、emcv是什么?
EMCV全称为EmbeddedComputer Vision Library,是一个可在TI
DM64x系列DSP上运行的计算机视觉库。EMCV提供了跟OpenCV完全一致的函数接口,通过EMCV,你可以轻松的将你的OpenCV算法移植到DSP,甚至不用改一行代码。目前EMCV已经支持IplImage, CvMat,CvSeq等基本数据结构,可使用cvCreateImage等创建和释放图像,以及contour检测等。EMCV刚刚启动,希望得到您的代码贡献:目前您可以通过subversion客户端获取源代码,源代码位于https://emcv.svn.sourceforge.net/svnroot/emcv
二、利用emcv编写自己的算法。
1、新建一个ccs3.3工程,取名为emcv,和ccs3.3使用手册中配置一样配置一下工程。
2、添加源代码到工程,这里要注意,我们只需要添加cpp和hpp文件即可,ccs会自动添加相应的头文件。但是这里会产生一个问题。
说没有找到cxcore.h文件,但是文件夹中明明有这个文件,网上的解决方法是要添加一个头文件路径说明,标识你头文件的路径。
具体做法是:project->buildoption->compiler->preprocess;
设置includesearch path为我们cxcore.h的路径;再次编译,发现这个问题解决了。
接着会出现:
这个问题是由于内存分配产生的问题,我们只要把dsp/bios configure文件中的mem configure修改一下即可,把compiler sections中的选项修改为SDRAM即可。
到此emcv编译就差不多通过了。
三、编写自己的emcv程序。
我这里实现读取一幅yuv422格式图片。流程如下。
在OpenCV中,图片的格式都是为IplImage,将OpenCV中的人脸检测移值到DSP中去的时候,要将视频格式YUV转换到IplImage,才符合OpenCV的数据结构,在YUV格式中,其中Y为亮度分量,UV为 {MOD}度分量。可以直接提取Y分量,可以得到灰度图像。
代码如下:
#include "cv/cv.h"
#include
#include
#include "guitar.h"
typedef char XDAS_Int8;
void convert_yuv_to_iplImage(IplImage *image,int width,int height)
{
XDAS_Int8*y;
inti;
for(i=0;i<240*320;i+=1)
{
image->imageData[i]=pGuitar240320_YCbYCr422[i]&0xff00;
};
}
int image_FFT2(XDAS_Int8 *outbuf,unsignedint width, unsigned int height)
{
inti,j;
IplImage*image = cvCreateImage(cvSize(240,320),IPL_DEPTH_8U,1);
convert_yuv_to_iplImage(image,width,height);
IplImage*dst=cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,1);
IplImage*tmp=cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,1);
cvErode(image,tmp,NULL,1);
cvThreshold(tmp,dst,125,255,CV_THRESH_BINARY);
while(1);//设置断点
};
int main()
{
XDAS_Int8*outbuf;
image_FFT2(outbuf,240,320);
}
四、运行代码
编写完成自己的代码后执行代码,会出现以下错误,
这是由于cvAlloc函数中使用了memalign分配内存的函数,所以当内存不足的时候,它没有可分配的内存时就会返回null。只要增大内存heap就可以实现。这里我们把SDRAM的heap增加到0x00100000;这样程序就可以运行了。
五、测试效果
由于ccs3.3查看图片的效果不是很好,只有yuv和RGB格式,这让我们的图片效果不明显, 所以我们借助了matlab强大的图像显示功能实现基于ccs3.3图像算法的编写。
1、编写matlab上save_ccs_data_file函数实现把图片保存为ccs可以使用的文件。
function save_ccs_data_file(I, filename)
fid = fopen(filename,'w+');
if-1 ==fid
error([' Failed to open ' filename]);
end
if strcmp('uint8', class(I))
bpp = 8;
elseif strcmp('uintl6', class(I))
bpp = 16;
else
error('Only 8-bit and 16-bit images aresupported');
end
fprintf(fid,'1651 1 0 0 0
');
[M N] = size(I);
I = double(I);
for ii=1:M
if 8==bpp
for jj=1:N/4
fprintf(fid,'0x%.2x%.2x%.2x%.2x
', ...
I(ii,4*jj:-1:4*(jj-1)+1));
end
elseif 16==bpp
for jj=1:N/2
fprintf(fid,'0x00%.2x00%.2x
', ...
I(ii, 2*jj-l), I(ii, 2*jj));
end
end
end % for each row
fclose(fid);
2、编写matlab上read_ccs_data_file函数实现把ccs提取的数据存储为matlab图片。
function I = read_ccs_data_file(filename,type,M,N1)
if strcmp(type,'uint8') | strcmp(type,'int8')
nbytes = 4; % each word has 4 bytes
elseif strcmp(type,'uintl6') |strcmp(type,'intl6')
nbytes = 2; % 2 bytes per word
else
error('Please specify a desired data-type,[u]int8 or [u]intl6');
end
fid = fopen(filename, 'r');
if -1 == fid
error(['Could not open ' filename]);
end
tline = fgetl(fid);
% last token in header gives us the length
header_data = sscanf(tline,'%x');
len = header_data(length(header_data));
if (0 == len)
% data length not defined, so compute it
% from the # of text lines in the datafile,
fclose(fid); % will reopen afterwards
len = how_many_lines (filename);
% get back to where we were prior to this
% diversion.
fid = fopen(filename, 'r');
tline = fgetl(fid);
end
N = sqrt(len*nbytes); % assumes squareimage matrix!
I = zeros(M, N1);
for ii = 1:M
if 2==nbytes % 16 bpp
for jj = 1:N1/2
tline = fgetl(fid);
I(ii, 2*jj-l:2*jj) = [sscanf(tline(3:6),'%x') ...
sscanf(tline(7:10), '%x')];
end
else % 8 bpp
for jj = 1:N1/4
tline = fgetl(fid);
p1 = tline(9:10); p2 = tline(7:8);
p3 = tline(5:6); p4 = tline(3:4);
I(ii, 4*(jj-1)+1:4*jj) =[sscanf(p1,'%x')...
sscanf(p2,' %x')...
sscanf(p3,'%x')...
sscanf(p4,'%x')];
end
end
end % for each image row
fclose(fid);
if 'u' ~= type(1) % unsigned-to-signedinteger conversion
halfway = 2^(32/nbytes-1)-1; % e.g., 127for 8 bpp
% find and replace those values that areactually negative
knegative = find(I>halfway);
offset = zeros (size (I));
offset (knegative) = bitshift(1,32/nbytes);% (1?8) or 256
I = I-offset;
end
eval( sprintf('I=%s(I);', type) );
function N = how_many_lines(filename)
fid = fopen(filename, 'r');
tline = fgetl(fid);
N=0;
while 1
tline = fgetl(fid);
if ~ischar (tline), break, end
N = N + 1;
end
fclose(fid);
3、完成matlab程序后便可以提取ccs数据。完成显示效果。
提取的亮度图片
腐蚀后的图片
阈值化的图片
为了方便算法的编写,我们后面修改了save_ccs_data函数,使其能够保存图片为.h文件方便ccs调用。
程序如下:functionsave_ccs_h(I, filename)
fid = fopen(filename,'w+');
if-1 ==fid
error([' Failed to open ' filename]);
end
if strcmp('uint8', class(I))
bpp = 8;
elseif strcmp('uintl6', class(I))
bpp = 16;
else
error('Only 8-bit and 16-bit images aresupported');
end
fprintf(fid,'#ifndef__GUITAR_YCBYCR422_H__
');
fprintf(fid,'#define__GUITAR_YCBYCR422_H__
');
fprintf(fid,'unsigned shortpGuitar240320_YCbYCr422[] = {
');
[M N] = size(I);
I = double(I);
for ii=1:M
if 8==bpp
for jj=1:N
fprintf(fid,'0x%.2x,
', ...
I(ii,jj));
end
elseif 16==bpp
for jj=1:N/2
fprintf(fid,'0x00%.2x00%.2x,', ...
I(ii, 2*jj-l), I(ii, 2*jj));
end
end
end % for each row
fprintf(fid,'};
')
fprintf(fid,'#endif');
fclose(fid);
由于不知道怎么上传图片所以把文档资源链接放在下面:
http://download.csdn.net/detail/xujiezhangjing/4527252