最近常用到OpenCV相关函数,在使用的过程中对函数的理解掌握不够,所以出现了很多的问题,现在将所遇到及理解的函数做了个相应的整理。
(1)CvFilter2D(const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor=cvPoint(-1,-1))
Src:代表的时输入函数。要求的是参数类型为IplImage*,有些网上资料说CvMat*也可以,但是我试了一下,没有成功,就算强 制转换成为IplImage*,编译不会报错,但是运行结果却不对,所以果断选择了IplImage*对象。
Dest:可以选择,但是注意的是它的宽度与原图要相对应。
(2)CvMat转换为IplImage
网上给的是如下代码:有此人成功了,都是先Load图像,再转换的。
IplImage* pImg = cvCreateImage(cvGetSize(mat),8,1);
cvGetImag e(matI,pImg);
编译通过,运行时触发断点,错误nChannel= 1,3。。。,检查代码 发现是pImg->nChannel这个变量在CvGetImag时变成了 2,如果导致在获取CvMat数据到IplImage对象时发生错误,相应的pImg->widthstep这个变量发生变化,从而存放及拷贝出错。
解决办法:只有通过循环,拷贝数据块,成功实现。
IplImage* pImg =cvCreateImage(cvGetSize(cDetectNest.m_p_matBwImg),IPL_DEPTH_8U,1);
BYTE *p_byDestData=m_p_matConnRegionImg->data.ptr;//这个数据对象很重要,看你CVMAT保存格式是怎样的,我是用的IPL_DEPTH_8U,而ptr对应UCHAR,刚好。
for (int i = 0; i < nImgHeight;i++ )
{
for (int j = 0; j < nImgWidth; j++)
{
pImg->imageData[i*pImg->widthStep + j] =p_byDestData[i*nImgWidth+j];
if (p_byDestData[i*nImgWidth+j] == 255)
{
int k = 0;
}
}
}
cvShowImage( "edge", pImg);
IplImage* pImg =cvCreateImage(cvGetSize(cDetectNest.m_p_matBwImg),IPL_DEPTH_8U,1);
BYTE *p_byDestData=m_p_matConnRegionImg->data.ptr;//这个数据对象很重要,看你CVMAT保存格式是怎样的,我是用的IPL_DEPTH_8U,而ptr对应UCHAR,刚好。
for (int i = 0; i < nImgHeight;i++ )
{
for (int j = 0; j < nImgWidth; j++)
{
pImg->imageData[i*pImg->widthStep + j] =p_byDestData[i*nImgWidth+j];
if (p_byDestData[i*nImgWidth+j] == 255)
{
int k = 0;
}
}
}
cvShowImage( "edge", pImg);
(3)关于创建 IplImage对象自动补齐
cvCreateImageHeader()//开辟图像头,但是没有数据空间
cvInitImageHeader();重新初始化头,
cvSetData()设置数据空间,
完成之后就成了一个完整的IplImage对象,但是它与cvCreateImage()创建的对象有些不一样,即使给定的宽度,高度相同。
不同之处:cvCreateImage()创建对象会对于宽度不是4倍数的,它会自动将存放widthstep置为4的倍数,与BMP图像保存宽度4字节对齐是一样的,但是Width还是设置的宽度。而通过上面步骤创建的则不会补齐,widthstep=width。
江 2014.03.04