我是做图像的,原来都是用VC里现成的东西来做,但是现在人家要求我重新定义一个图像格式,可是定义完了之后的图像处理速度很慢,而且所有的图像(2值,灰度,真彩)处理速度基本上都一样。人家说不行,说2值应该是彩色的1/3左右,但是我不知道2值为什么会比彩色慢的原因,所以不知道怎么改,希望大家指点~!小女子不胜感激~!
解决方案 »
- XML加密与解密问题!
- 如何获取点击处的frame属性!!!
- 请教一个关于CString和UNICODE的问题
- 急!!急!!!我用CDaoDatabase大开了Access关闭不了!!(高手们请帮忙呀!!)
- 求教:如何获得EMF文件?分不够的话可以再开一贴
- 请问如何把int转换成cstring?
- 怎样把数组的值写进数据库!而后又怎样能读出来!!
- 关于打印.. 高手请进
- 如何将我VC中一个按钮控件的使能与否自动与一个变量关联
- 做类似于oicq聊天室那样的东西怎么做的,是不是窗口线程,有无例子,大家帮忙,急!!!!!!!!!!!!!
- 关于 include
- 怎样将CList<int,int>变量在函数间传递呀?
二值处理的速度比彩色的快的原因也只能如此
但是也要看是如何处理的
比如查找边界的时候,二值也许比彩色的更慢呢,因为要从byte数据当中解释出来具体的位来,没有直接用byte判断快。图像处理的一些基本算法和代码可以在这里看到:http://www-scf.usc.edu/~flv/ipbook/
插值的时候颜色提取都有可能用到位操作的,没准谁快,24或者32位的比2值快,16和256的比2值慢。
我用我的算法进行旋转,二值的图像(2136*2848)旋转时间为4.254132S,算很慢么?对了忘了说了,我用的是C#,很麻烦,不像原来用VC里面位图的格式,什么文件头之类都定义好了的,在这里要自己定义。而且读进来的时候要转换为我们公司自定义的图像格式,之后在旋转,之后显示的时候还要借助Bitmap(因为现在还没开发出来怎么直接显示)。 我的速度很慢么?
值得一说的是原来用VC写的时候同样的东西为什么不到1S就出来了~!很郁闷~!
我的程序是读文件时扫描1次,旋转扫描1次,把自定义文件转化为Bitmap扫描1次,显示扫描1次。
相同的算法用Bitmap直接做,相当于扫描3次,需要时间更长啊~!要十几秒:(
for(int i=0;i<vout_Image.PixelInfo.Length;i++)
{
vout_Image.PixelInfo[i].Mono = 0;
}
int PX,PY,k1,k2;
int in_OX,in_OY;
int out_OX,out_OY;
double radRotate;
double cosA, sinA; in_OX = vin_Image.Width / 2;
in_OY = vin_Image.Height / 2;
out_OX = vout_Image.Width / 2;
out_OY = vout_Image.Height / 2;radRotate = angle / 57.2957795;
cosA =Math.Cos(radRotate * (-1));
sinA =Math.Sin(radRotate * (-1));
for (int j = 0;j < vout_Image.Height ; j++ )
{
for (int i = 0;i < vout_Image.Width ;i++ )
{
pointcolor pc= vin_Image.GetPixel(i,j); PX = i - in_OX;
PY = j - in_OY; k1 = (int)( ( PX * cosA - PY * sinA ) + in_OX );
k2 = (int)( ( PX * sinA + PY * cosA ) + in_OY );
if(k1>0&k1<vin_Image.Width&k2>0&k2< vin_Image.Height)
{ if(pc.Mono ==1)
vout_Image.PixelInfo [(vout_Image.Height -k2-1)*vout_Image.Width +k1].Mono =1;
else
vout_Image.PixelInfo [(vout_Image.Height -k2-1)*vout_Image.Width +k1].Mono =0;
}
}
}
你看看你的程序,为了一个像素,有N个判断,N个成法,N个超级慢的三角函数,加减与不及其数,竟然还一个函数调用.读写方式也违背WRITEBACK的CPU缓存规则.
我的基于指针的类似算法像素循环里只有2,3个计算,都是加减之类的快指令,速度保守估计也比你要快几十倍.不过我的程序比你的长得多,至少5倍以上.只不过我的旋转和你的规则不太相同,给你也没用.
简单的说,你要把复杂计算搬到像素循环外面,尽量按写像素X方向做底层循环
另外你先根据角度计算一个tg,根据斜率在原图象中走斜线,取得的像素在新图象中走水平横线,这样CPU的CACHE负担比较轻.
不要每个点做好几个是否在范围内的判断,先找到扫描线中第一个和最后一个在范围内的像素,再做FOR循环
之所以要你的二值图旋转比彩图旋转快,是因为彩图的旋转要在同一点上计算三个值!而二值图只需要计算一个值!
使用vin_Image.GetPixel(i,j)和vout_Image.PixelInfo 太慢了.
没有用过java不知道是否可以用DIB来直接获得图像数据.会快很多
建议:循环里面整个计算太多,特别是乘除;CPU计算里面乘除比较耗费指令周期,最好改变算法,除法最好改乘法或者加减;还有什么正弦余弦之类的更是耗费时间(可能是利用级数实现的),建议事先计算一些数值做好做个表格,查表实现(不过可能耗费内存多些)。
浅见,仅供参考,没有代码。