旋转图像.pbm Haskell

时间:2012-05-02 02:38:43

标签: haskell matrix rotation ppm

我需要有关haskell中旋转或旋转矩阵的帮助

我有一个数据类型为RGB的列表列表:

data RGBdata= RGB Int Int Int

m = [[(RGB 0 255 255),(RGB 255 0 0)],[(RGB 255 255 255),(RGB 255 0 0)]]

更好看我有一个矩阵2x2:

m = [[(RGB 1 2 3),(RGB 4 5 6)],
     [(RGB 7 8 9),(RGB 1 5 9)]]

我需要90°旋转,我的意思是:

m = [[(RGB 7 8 9),(RGB 1 2 3)]
     [(RGB 1 5 9),(RGB 4 5 6)]]

扩展我的解释,我有2种数据类型:

data RGBdata= RGB Int Int Int
data PBMfile= PBM Int Int [[RGBdata]]

我的功能收到:

spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y ((transpose . reverse) l))

其中'x'和'y'分别是colums和rows的数量(可能有助于执行该功能)。

我尝试用你的anwer向左旋转90°,图像结果错误。

我试试

spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y ((reverse . transpose) l))

spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y ((transpose . reverse) l))

spin :: PBMfile -> PBMfile
spin (PBM x y l) = (PBM x y (((map reverse) . transpose) l))

旋转图像但不起作用。

结果类似于

http://imageshack.us/photo/my-images/52/catmc.jpg/

2 个答案:

答案 0 :(得分:7)

TL; DR:transpose . reverse

如果您计划使用列表来存储大图像,请记住它可能效率低下,因为每个像素有五个盒装值(很多字节)。使用未装箱的Vector或Array会更有效。只是给你一个抬头。

那就是说,让我们根据他们对图像所做的事情来看一下列表操作。

> let demo f = mapM_ print $ f m
> demo id
[RGB 1 2 3,RGB 4 5 6]
[RGB 7 8 9,RGB 1 5 9]
> demo reverse
[RGB 7 8 9,RGB 1 5 9]
[RGB 1 2 3,RGB 4 5 6]
> demo (map reverse)
[RGB 4 5 6,RGB 1 2 3]
[RGB 1 5 9,RGB 7 8 9]
> demo (transpose)
[RGB 1 2 3,RGB 7 8 9]
[RGB 4 5 6,RGB 1 5 9]
  • reverse垂直翻转图像(通过反转行)

  • map reverse水平翻转图像(通过反转每行中的像素)

  • transpose沿着\对角线翻转图像。

现在,找一张纸,弄清楚如何根据这些操作执行所需的旋转(如果你的纸是矩形的,建模transpose很棘手)。请记住,只要看到纸张背面,图像就会显示为镜像。由于这些操作中的每一个都会转动纸张,因此需要偶数个来执行旋转。

您可以使用reversemap reverse进行的唯一轮播是将文件翻转过来。这意味着您需要transpose将图像旋转90°。

transpose(对角线翻转)后跟reverse(垂直翻转)将图像旋转90°到

> demo (reverse . transpose)
[RGB 4 5 6,RGB 1 5 9]
[RGB 1 2 3,RGB 7 8 9]

另一方面,reverse(垂直翻转)后跟transpose(对角线翻转)将图像旋转90°到(你想要的):< / p>

> demo (transpose . reverse)
[RGB 7 8 9,RGB 1 2 3]
[RGB 1 5 9,RGB 4 5 6]

答案 1 :(得分:3)

如果我理解正确,您似乎需要map reverse . transpose,其中transpose位于Data.List

> let x = [[1,2,3], [4,5,6], [7,8,9]]
> map reverse . transpose $ x
[[7,4,1],[8,5,2],[9,6,3]]

请注意,如果您的输入列表足够大,这可能比必要的慢,但如果您的列表是1000 x 1000,或者如果您在紧密的内循环中执行此操作,则可能只会发挥作用。