| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2571 人关注过本帖
标题:[讨论]给大家出一个算法方面的问题
只看楼主 加入收藏
kk4868
Rank: 1
等 级:新手上路
帖 子:77
专家分:0
注 册:2007-6-3
收藏
得分:0 
一个原始图片,宽为W,高为H,可以每次置换H个点,分W-1次完成操作,我试验了一个7*4的矩阵是可行的
但是置换的规律太难找了,呵呵
这样只需要增加一个像素的临时空间

[此贴子已经被作者于2007-8-9 13:32:53编辑过]


2007-08-09 13:20
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
以下是引用kk4868在2007-8-9 13:20:11的发言:
一个原始图片,宽为W,高为H,可以每次置换H个点,分W-1次完成操作,我试验了一个7*4的矩阵是可行的
但是置换的规律太难找了,呵呵
这样只需要增加一个像素的临时空间

呵呵,我想明白了。不过这样空间是省了,但实现可能太慢了。

2007-08-09 14:29
kk4868
Rank: 1
等 级:新手上路
帖 子:77
专家分:0
注 册:2007-6-3
收藏
得分:0 

其实也不是太慢,毕竟都是对内存的数据移动吗,而且是在一个一维数组内。很少的点要两次移动。
感觉速度还可以吧。
就是规律我没有总结出来,老董总结出来了?详细说说啊


2007-08-09 16:52
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
规律还在想,孙靖那套的规律好找些,嘿嘿。
2007-08-10 08:34
RockCarry
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 
Jig的算法时间复杂度还是有点高,而且这里要求处理的数据量很大。2440的主频为400MHz,如果使用传统算法,在旋转1000x1000大小的图片就需要2s左右的时间。如果采用Jig的算法,在处理更大的图片时,则会需要更多的时间,恐怕给用户的感觉就是像死机一样了。
还来我想了,用临时文件来存放大量的数据,临时文件将会保存到SD卡上,这样文件的长度可以说是不受限制。旋转时,先把结果数据写到临时文件,然后再从临时文件读回数据。想来似乎可行,后来试验了一下,发现SD卡的读写速度跟不上,目前SD卡的读写速度能到达1MB/s(这个已经是我经过许多优化才取得的成果),这样算下来,旋转一个图片消耗在文件读写上的时间就需要20s以上,这是无法接受的。
2007-08-10 19:20
RockCarry
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 
到目前为止,还是没有找到更好的旋转算法。这个算法对时间和空间的要求都比较高。
2007-08-10 19:21
RockCarry
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 
不过这个问题到后面有了新的解决办法。
其实项目需要完成的是一个图片浏览器,能够支持 JPEG 和 BMP 图片的浏览。BMP 的显示可以借助 WinCE API 来实现,JPEG 图片的解码则选用了 Independent JPEG Group 的一个 JPEG Codec。数码产品的 LCD 屏只有 480x272 大小。浏览器中,提供了图片原始大小、图片缩放、旋转等功能,在图片不能完全显示时,给出水平滚动条和垂直滚动条供用户拖动。在调用 JPEG 解码库时,根据图片的原始大小创建了一个位图对象,然后将 JPEG 图片解码到这个位图对象中。因此对于大尺寸的 JPEG 图片,就需要占用很大的内存。然而,实际的 LCD 只有 480x272 大小。因此,我们打算,在 JPEG 解码的时候,就对尺寸的图片进行缩放,缩放到合适的尺寸,使其既能保证内存足够,又能保证显示效果。因为在浏览大尺寸图片时,其实图片都要经过缩放处理(都是缩小),因此,对于大尺寸的图片在解码时就进行缩放处理,几乎不过影响用户浏览图片的效果,只会在图片原始大小,或者放大时,会有图片质量上的损失。
根据这个思路,我们将图片浏览器可用的内存空间定为8MB,其中4MB用于位图的存放,另外4MB则是用于旋转等处理的临时缓冲区。在遇到大图片时,先判断其所需要的内存是否大于4MB,如果是,就在解码时进行缩放处理。然后,剩下的问题就已经不是问题了。
也不必去研究前面的算法如何实现。当然,工程上的实现往往都是这样,尽量避开技术难点,采用最直接、最简单的办法解决问题。
然而,如果是单纯将这个问题当作算法来研究的话,我认为还是有价值的。我也会继续思考这个问题的解决办法。大家也帮忙想想。
2007-08-10 19:49
jig
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
帖 子:530
专家分:242
注 册:2005-12-27
收藏
得分:0 
我也先过啦,似乎在效率上是很难兼顾

开始我想看是不是直接采用按转换规律直接在屏幕上打点,可我不知道你的屏幕型号,可液晶一般是慢速器件,也许那样在旋转时其实就是重绘过程,这样图片的显示就有个过程(可能是慢慢刷出来的),我想这样也不能满住要求

至于以文件形式,我想也更不可能SD卡的读写。。。。。。黑嘿。

要不就扩内存吧,看能不能控制一下成本。

个人网站 -  http://.h001.
2007-08-10 23:11
hjj1123
Rank: 1
等 级:新手上路
帖 子:198
专家分:0
注 册:2006-7-29
收藏
得分:0 

我没有看动JIG的算法。自己想了个,大家看看行不。这个办法理论上非常好,可是我有个地方没解决,内存开销回比较大,但是能满足LZ的要求。
原始图像
a b c d
e f g h
i j k l
int w1 = 4;
int h1=- 3;
BYTE pdata[] = { a, b, c, d, e, f, g, h, i, j, k, l };
旋转后的图像
i e a
j f b
k g c
l h d
int w2 = 3;
int h2 = 4;
BYTE pdata[] = { i, e, a, j, f, b, k, g, c, l, h, d };
JIG也说过了,转换的规律是
X1=y0;
Y1=w2-1-x0;
(x0,y0,x1,y1分别是转换前后的坐标,没有考虑字长),称为公式1
原始图像:
|(0,0),(0,1),(0,2),(0,3)|
|(1,0),(1,1),(1,2),(1,3)|
|(2,0),(2,1),(2,2),(2,3)| int w1 = 4; int h1=- 3;
旋转后的图像:
|(2,0)/ (0,0),(1,0)/ (0,1),(0,0)/ (0,2)|
|(2,1)/ (1,0),(1,1)/ (1,1),(0,1)/ (1,2)|
|(2,2)/ (2,0),(1,2)/ (2,1),(0,2)/(2,2)|
|(23)/ (3,0),(1,3)/ (3,1),(0,3)/(3,2)| int w2 = 3;int h2 = 4;
/前面是转换后的数据在转换前数组中的坐标,/后是在新数组中的坐标;
由于BYTE pdata[] = { a, b, c, d, e, f, g, h, i, j, k, l }一维的形式按行顺序存放,所以位置需要转换一下,
公式为:
x2=(x1*w2+y1)/w1;
y2=(x1*w2+y1)-y2*w1;
称为公式2
(0,0)(原图像中的位子)---公式1---(0,2)(现在图像中的位子)-- 公式2---(0,2) (原来图像中被占用的数据位子,也是第二次原图像中的位子)----公式1--(2,2) (第二次 现在图像中的位子) -- 公式2---(2,0)(依次类推……) ---公式1-(0,0) (依次类推……)
注意现在开始循环了。这是我刚开始时没想到的,我以为它会持续下去直到完成。
0 1 2
0 |(2,0), ,(0,0)|
1 | , , |
2 | , ,(0,2)|
3 | , , |
这是一次循环所填的点,在做几次循环就可以完成整个数组填充。现在麻烦有两个:
1:如何判断已经完成整个数组填充?
2:起始点如何选择?
对于第一个问题可以设置一个变量,在每填充一次计一次数,让它和总数比较,用以判断是否完成。这个应该难度不大。 第二个问题我还没有解答,我试过数组的对角线,边线上的点的坐标作为起始点,但是遗憾没有完全包含整个数组。想到了最笨的办法,就是将每个点都假设为起始点,建立一个数组START[4000000][2] 刚好是LZ剩下的八M空间,元素为(0,0),(0,1),(0,2)……….(1998,1999),(1999,1999),然后进行前面描述的循环,每填充一个点,便在START数组中删掉相应坐标,完成一次循环后在START数组中拿第二个点做起始点开始下一次循环,同时删掉第一个起始点,直到START数组为空。

这是没办法的办法,如果能找到办法提取所有的起始点坐标那就完美了,最多需要几十K的空间,那像这笨办法要那么多的空间。
有不妥的地方请大家明示!!!


qq:674940174
2007-08-11 01:14
RockCarry
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 
大概懂了 hjj1123 的算法原理。即找一个起始点,计算出其旋转以后的坐标,根据这个坐标,计算出旋转后在数组中的实际偏移地址,然后将这个地址上的元素与起始点的元素进行交换。然后再对起始点进行处理,此时起始点保存的数据实际上是前面交换过来的数据,这个数据在原始图像中的坐标也可以算出来,然后来根据这个坐标计算出旋转以后的坐标,然后再如此重复。
2007-08-11 13:56
快速回复:[讨论]给大家出一个算法方面的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016141 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved