请小吉哥哥来帮忙看!~

DooDu 2005-06-22 12:29:27
加你qq了,可没反应。。。-_-||
我还是发贴说吧~分就这么多了。。
我在用vb调用拿c写的dll,dll使用了intel的图象处理库opencv,opencv中的图象是IplImage,它的头格式:

typedef struct _IplImage
{
int nSize; /* IplImage大小 */
int ID; /* 版本 (=0)*/
int nChannels; /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */
int alphaChannel; /* 被OpenCV忽略 */
int depth; /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */
char colorModel[4]; /* 被OpenCV忽略 */
char channelSeq[4]; /* 同上 */
int dataOrder; /* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道.
只有cvCreateImage可以创建交叉存取图像 */
int origin; /* 0 - 顶—左结构,
1 - 底—左结构 (Windows bitmaps 风格) */
                ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
int align; /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */
int width; /* 图像宽像素数 */
int height; /* 图像高像素数*/
struct _IplROI *roi;/* 图像感兴趣区域. 当该值非空只对该区域进行处理 */
struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */
void *imageId; /* 同上*/
struct _IplTileInfo *tileInfo; /*同上*/
int imageSize; /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/
char *imageData; /* 指向排列的图像数据 */
    ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
int widthStep; /* 排列的图像行大小,以字节为单位 */
int BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */
int BorderConst[4]; /* 同上 */
char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */
}


因为是vb调用这个dll,这个dll的功能是对图象进行计算(不修改),返回几个值;我的思路是:让vb把自己图象的pvData指针传给dll,然后赋给IplImage的imageData指针;但imageData指向的是char型,我不知道是不是和bitmap的数据类型一致,同时,我让origin=1;然后,我没有处理图象,只是调用了opencv的一个函数保存下图象,发现是黑的,就是说没指对!

真不清楚是怎么回事了。。还有,我在vb的api声明里 byval picptr as long,这个 long 意思是picptr为long型,还是picptr是指向long型的指针呢?如果这个是刚才pvdata那个指针,那么在c里如何写函数参数呢?

谢谢拉~
...全文
196 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
DooDu 2005-06-22
  • 打赏
  • 举报
回复
果然是我的问题!没注意到opencv是不处理alpha通道的,但它保留了对它的支持,呵呵,再一次谢谢小吉哥哥拉!
结帖!
homezj 2005-06-22
  • 打赏
  • 举报
回复
你的问题应该是出在色深上,depth是怎么指定的?

从数据对比上看,很显然,是把32位色转成24位色处理了。处理结果也是正确的,但你在显示到设备上时,可能没有进行过相应的色深转换。
也就是说,
pvdata指的内容是一个3*2*32的位图(从下向上的扫描行)
imageData指向的内容是一个3*2*24的位图(从上向下的扫描行)
两个位图数据是一致的。
DooDu 2005-06-22
  • 打赏
  • 举报
回复
而且我通过debug,发现frame->origin=1只是单纯让origin写为1,之后存储顺序并没改变,所以我想,origin=1,只是通知opencv,在处理的时候要倒着处理,而我确实“通知”了呀!
DooDu 2005-06-22
  • 打赏
  • 举报
回复
现在问题解决了一半~`可又出现了新问题!
我把图象的pvData指针传递过去,在c中写:

int __stdcall JS( char *picptr )//这个是vb传来的pvdata指针
{
IplImage *frame = 0;
frame = cvCreateImage( cvSize(320,240), 8, 3 );//这个cvcreateimage是创建图的函数,将头结构自动创建好。cvsize是设置图象大小的函数,在vb中传来的图片也是320*240的。
frame->imageData=picptr;//赋值
frame->origin=1;
return 0;
}

然后我在c中保存该图片,然后打开,发现:图片出现重影,花块,与原图严重不符!可在虚影下可隐约看到原图的部分内容(变色,颠倒,不清楚。)

我开始怀疑是顺序问题,然后我分别用vb和opencv的c大开那个图片,用winhex得到了vb中pvdata指向的区域内容以及imageData指向的内容:

(为了简化,我让他们读一个相同的图象,大小3*2)
vb的pvdata指的内容:

044C0000 E9 E3 E4 00 00 E9 E3 00 E4 00 E9 00 8C 93 8D 00
044C0010 00 62 69 00 00 00 FF 00 00 00 00 00 00 00 00 00

opencv读出内容后imageData指向的内容:

00A01A80 8C 93 8D 00 62 69 00 00 FF 00 00 00 E9 E3 E4 00
00A01A90 E9 E3 E4 00 E9 00 00 00 00 00 00 00 00 00 00 00

可以看出,两片内容有相似性,但顺序不同。我还没自己检查,估计是存储顺序不同!所以,我估计我读出“问题图片”的原因是这个!
可是我用 frame->origin=1 把origin给置位了啊?

请小吉哥哥检查~
homezj 2005-06-22
  • 打赏
  • 举报
回复
哎!QQ平常不开,刚看了短消息才打开。
这个问题有些复杂,结构的定义很关键,
char *imageData应该是一个指向Byte数组的指针,在结构中只能用Long,写入该值时,可使用varptr函数。
与API找交道,情况较复杂,一般需根据函数原型的要求,byval传long型数据,如果,函数原型要的是数值,它就会被当成数值,若要的是内存地址,它就会被当成指针,正常情况下,API声明中Long型是没有按址传递的。
DooDu 2005-06-22
  • 打赏
  • 举报
回复
up

7,762

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧