3维数组的问题是数组索引的计算错了。还有平时所说的1024*768是列*行的,脑子中一般认为扫描的顺序是先行后列,
这样的话768需要在外循环,1024在内循环
当然,只要索引计算正确,先行后列和先列后行应该没什么区别
计算otsu错误是因为图像已经归一化到[0,1],otsu中用到的是[0,255],这样看来,不应该一开始就把图像归一化进行处理
*****2009-7-25晚,dll的调试问题解决,开始做匹配
匹配首先是模板问题,c++访问access 数据库的方法不好。每个模板生成一个模板文件
模板文件是自定义的数据结构,传入到dll中即可
匹配算法放在DIPBasic中是否适合?匹配点能否算是一种特征,基于模板这个先验知识的特征
这样的话,就做一个DIPFeatures.dll包括基于模板的特征点,sift特征点等
hough变换,等又该放在那里呢?hough变换,求连通区还是放在DIPBasic中
以后分类做个classifers 包括hopfield ,svm,
现在的问题是获得(search)匹配点(叫做最佳匹配点bestMatchPoint),匹配点排序,过滤,
模板文件.dat=模板是变长的,需要定义几个结构,模板文件是结构文件
还用到结构数组 BTMPtemplate=
记录文件的操作,c++怎么做的?可以只传文件的路径,就完成search操作
1.c#中做access导出到一个dat 文件,2.dll实现dat到一个模板数组
能基本就基本的原则,采用struct来实现,structure如何save to file呢?
每个dat文件可以进行加密,只允许某个电脑使用
dat=128位密码区先空着+模板数int32,【模板名称string[6]】【模板权值int32】【数据区大小int32】【数据区】
******2009-7-26 早
算法还是用c++写的比较快,同样的预算,c++是700ms,c#是4000ms,提高了接近6倍
计算模板大小在生成模板数组的时候做,这样可以不用修改数据库,和以前的程序,也可以在导出dat的时候做,
******2009-7-26晚
dat=128位密码区先空着+【模板名称char[12]】【模板权值int32】【宽度】【高度】【数据区】
数据区是byte为单位的点阵
commonVar.cs中的BTMPtemplate类完成数据库到dat文件的生成.
DIPFeatures.dll中的BMTPtemplateRead 完成dat 到内存结构数组的转换
初步形成验证码识别的解决方案一个是匹配法识别,一个是分割法识别
btmp文件可以作为共用的样本文件.
能用匹配法识别的优先采用匹配法识别,识别率达到85%以上
争取30号前完成匹配法识别的论文,
15号前完成sift的实验,这样9月份还可以出一个论文。论文数能达到要求
还有灯泡项目是一个重点,这几天就得研究下()
***********2009-7-27 早
现在的问题是处理struct的问题。数据不定长,如何读取最方便
读入数据的时候,数组的长度也需要事先定义好,如何根据需要来定义,好像行不通啊
动态数组通过指针来实现,2维的数组用1维的来实现char *
如何从文件中读取一个整数成了一个问题
要查看二进制文件,可以用debug filename ,-d来实现
f.open() 的文件路径不对,如果f.open("c:/csdn.btm")可以,f.open(templateFile)则rdstate=3
delete[] test出错,不delete[] 会有stack around test is corrupt的提示,程序能正确执行
*********2009-7-28
文件路径的问题,暂时用如下方法解决,但是这个方法不支持中文路径
char[] fname=this.openFileDialog1.FileName.ToCharArray();
int totalTemplate = BTMPtemplateCount(fname);
[DllImport("DIPFeatures.dll")]
public static extern int BTMPtemplateCount(char[] templateFile);
结构中指向不定长的数组,好像实现不了,毕竟这部分内存是在dll中分配的,问题比较多,还是用长度为1000的固定长度吧
这样,模板的大小w.h<1024=1k的都可以,但是c#中的结构,似乎可以不指定数组成员的大小。c++则不行
现在的问题是,从dll返回时有受保护的内存,访问错误的提示信息,改成传intPrt 不会报错,但传回的数据位置乱了
Tname和Datap两个char[]都是null
这里主要应该是结构里包含数组的问题,试了下去掉char[]字段,结果就正确了。
********2009-7-29
搞了很多天了。。。
数据应该是能被正确读出了,不过还有点小错误,Tname[11]实际标的时候fieldoffset有点小问题
c++中的结构如下
struct BTMPtemplate
{
char Tname[11];
__int32 weight,targetArea,w,h;
char dataP[1024];//指向2D点阵的一个指针 ,2D点阵已经1D化,这里原来想用不定长,结果实现不了
};
c#中要声明如下
[StructLayout(LayoutKind.Explicit,Size=1051) ]
public unsafe struct BTMPtemplate
{
[FieldOffset(0)]public fixed byte Tname[11];//这里的char 好像是2个字节的,msdn上有的说明
[FieldOffset(12)]public int weight;
[FieldOffset(16)]public int targetArea;
[FieldOffset(20)]public int w;
[FieldOffset(24)]public int h;
[FieldOffset(28)]public fixed byte dataP[1024];//指向2D点阵的一个指针 , ,2D点阵已经1D化
}
注意这里的[FieldOffset(12)],本来应该是11才对。既然offset是从0开始的。。
不过这样做就能用了,调用如下:
int totalTemplate = BTMPtemplateCount(fname);
BTMPtemplate[] templateArray=new BTMPtemplate[totalTemplate];
IntPtr p2 = Marshal.UnsafeAddrOfPinnedArrayElement(templateArray, 0);
BTMPtemplateRead(fname, p2,totalTemplate);
接下去的问题是数组赋值的问题,可能需要copy了
还有结构数组的排序问题,char数组是否相等的比较
还有动态数组的创建问题
1次过滤和2次过滤的代码似乎有冗余,1次过滤去掉距离近的相同,2次过滤去掉距离近的不同字符
总之,距离近的,只取匹配度最大的,排序以后得到匹配度最大的点
不过如何处理权值呢?对所有匹配点做加权显然是低效的,所以还是用2次过滤的方法吧
出现了一个"int"前面应该有;号的错误,原因是.h文件中函数声明后面的;忘加了
现在的问题是匹配结果还不对,把预处理以后的结果显示出来看看?
加权效果也没有做起来。先把匹配结果搞对先,30,31号两天希望能把这个论文结束掉
*******2009-7-30 排序问题,
//用于对BTMpoint的排序,排序调用qsort
int BTMPcompare(const void *ele1, const void *ele2)
{
struct BTMPoint *px,*py;
px=(struct BTMPoint *)ele1;
py=(struct BTMPoint *)ele2;
if((*px).p< (*py).p) //这个地方要注意,px,py是指针,px.p是不行的,px->p则可以,或者如代码
return 1;
else
return 0;
}
//排序
int BTMPqsort(BTMPoint *btmpResult,int count)
{
qsort(btmpResult,count, sizeof(struct BTMPoint),BTMPcompare);
return 0;
}
**********200907031图像切割,返回一个数组
返回一个数组,还得返回数组的维数,
好像还得实现定义接收数组的长度,所以还是只返回长度来的简单
int imgCut(double *imgBegin,int D1,int D2,int marginUp, int marginDown, int marginLeft, int marginRight,int targetValue,int targetMinCount,int *rx,int *ry,int *rex,int *rey );
对图像进行剪切,支持积分投影,返回结果的起始坐标
在调用的语言中copy这个数组
//只获得区域坐标,还得自己拷贝出来
imgCut(p3,d1,d2,1,1,1,1,0,2,ref x,ref ex,ref y,ref ey);
int newd1, newd2;
newd1 = ex - x;
newd2 = ey - y;
double[,] tmpbw = new double[newd1,newd2 ];
for(int ii=x;ii<ex;ii++)
for (int jj = y; jj < ey; jj++)
{
tmpbw[ii - x, jj - y] = commonVar.imgBW[ii, jj];
}
***********2009-8-5
好几天没动手了。
今天碰到的问题是,参试对c++返回的结构数组进行读操作,结果出错
“不能使用非固定表达式中包含的固定大小缓冲区。请尝试使用 fixed 语句。”
可以使用unsafe语句和fixed语句来解决,如下:
unsafe
{
for (int i = 0; i < 100; i++)
{
fixed (char * p = commonVar.btmpResult[i].Tname)
{
this.textBox3.Text += *p + ":" + Math.Round(commonVar.btmpResult[i].p,3)+"(" +commonVar.btmpResult[i].x+","+commonVar.btmpResult[i].y+")"+ "/r/n";
}
}
}
用原来的代码识别出18个可能位置,用新的代码有154个,说明某个地方还有错误,而且识别结果只有0和1
*************2009-8-6
终于得到正确的匹配结果了,现在的问题是排序好像不太正确,郁闷了.原来是compare函数写错了,对照msdn的定义最后结果如下
int BTMPcompare(const void *ele1, const void *ele2)
{
struct BTMPoint *px,*py;
px=(struct BTMPoint *)ele1;
py=(struct BTMPoint *)ele2;
if((*px).p< (*py).p)
return 1;
else
if((*px).p== (*py).p)
return 0;
else
return -1;
}
每一步都有错误,发现过滤也不行,找到原因是字符串比较的问题
终于搞定了,修改后的代码,匹配速度竟然提高了70倍左右,太惊人了