所以我有一个位图,它是一个int列表,每个像素代表rgb 3个索引。 图像的一行是一个列表,我正在尝试递归编辑此int列表列表并吐出另一个int列表列表。问题是,当我到达行的末尾时,我希望它创建另一个列表。现在,代码每行创建一个像素,每个列表创建3个值,并使图像直线向下,因此每个递归调用创建一个新列表。我希望它在没有达到宽度结束时继续在同一个列表上。这里的代码更有意义,因为我很难解释它。
let rec GrayscaleImage(width:int, widthVar:int, image:int list list) =
match image with
|[] -> []
|_ -> let r = image.Head.Head
let g = image.Head.Tail.Head
let b = image.Head.Tail.Tail.Head
let average = (int)((r+g+b)/3)
if widthVar > 3 then [average; average; average] :: GrayscaleImage(width, widthVar - 1, image.Tail.Tail.Tail)
else ???
首先在if之后它将创建一个新的列表,我希望它继续平均列表。(它是灰度图像btw)然后在其他我知道它应该做的事情就像在if上做的那样但可能不完全一样。我对如何去做这件事感到非常困惑。任何帮助都将不胜感激。
编辑: 我在以下代码中取得了一些进展
let rec BuildRowGrayscale(cols:int, a:int) =
match cols with
|0 -> []
|_ -> a :: a :: a :: BuildRowGrayscale (cols-1) a
let rec GrayscaleImage(width:int, height:int, depth:int, image:int list list) =
match image with
|[] -> []
|_ ->
let r = image.Head.Head
let g = image.Head.Tail.Head
let b = image.Head.Tail.Tail.Head
let avg = (int)((r+g+b)/3)
(BuildRowGrayscale width avg) :: GrayscaleImage(width, height, depth, image.Tail)
但它拒绝在(BuildRowGrayscale width avg)
和BuildRowGrayscale (cols-1)
处进行编译
“此值不是函数,无法应用”
答案 0 :(得分:3)
发表评论后,我认为这就是你要做的事情:
let rec GrayscaleImage image =
let rec BuildRowGrayscale =
function
| [] -> []
| r::g::b::rest ->
let avg = (r+g+b)/3
(avg :: avg :: avg :: BuildRowGrayscale rest)
| _ -> failwith "Invalid image"
match image with
| [] -> []
| row::rest -> BuildRowGrayscale row :: GrayscaleImage rest
或使用List.replicate
和List.map
:
let GrayscaleImage =
let rec BuildRowGrayscale = function
| [] -> []
| r::g::b::rest -> List.replicate 3 ((r+g+b)/3) @ BuildRowGrayscale rest
| _ -> failwith "Invalid image"
List.map BuildRowGrayscale
很抱歉,但是您指定宽度的事实让我觉得您也在改变原始结构,但如果结构没有改变,您不需要指定宽度,它就是&#39 ; s隐含在原始结构中。
答案 1 :(得分:1)
我假设image
包含您图像的像素。由于您只进行按像素操作,因此您只需映射外部列表。
let GrayscaleImage =
let avg = function
| r::g::b::_ ->
let average = (r+g+b)/3
[average; average; average]
| _ -> failwith "expected 3 colors"
List.map avg