VisualWorksで画像のエッジ抽出してみました。
"画像のロード" img := (ImageReader fromFile: '/path/to/your/image/file') image. newImage := img copyEmpty. "画像のグレイスケール化" img pixelsDo: [:x :y | pxColor := img valueAtPoint: x@y. ntscGray := (pxColor red + pxColor green + pxColor blue) / 3. newPxColor := (ColorValue red: ntscGray green: ntscGray blue: ntscGray). newImage atPoint: x@y put: (img palette indexOfPaintNearest: newPxColor). ]. "ラプラシアンフィルタでエッジの抽出" edgedImage := newImage copyEmpty. laplacian := #(#(0 -1 0) #(-1 4 -1) #(0 -1 0)). 1 to: (newImage width - 2) do: [:x | 1 to: (newImage height -2) do: [:y | | Red Green Blue | Red := Green := Blue := 0. 1 to: 3 do: [:a | 1 to: 3 do: [:b | pxColor := newImage valueAtPoint: (x+a-2)@(y+b-2). Red := Red + (pxColor red * ((laplacian at: a) at: b)). Green := Green+ (pxColor green * ((laplacian at: a) at: b)). Blue := Blue + (pxColor blue * ((laplacian at: a) at: b)). ]. ]. "ここをもう少し綺麗にかけるとうれしい ifTrue: ifFalseをネストすればいいかな" Red>1.0 ifTrue: [Red := 1.0]. Red<0.0 ifTrue: [Red := 0.0]. Green>1.0 ifTrue: [Green := 1.0]. Green<0.0 ifTrue: [Green := 0.0]. Blue>1.0 ifTrue: [Blue := 1.0]. Blue<0.0 ifTrue: [Blue := 0.0]. newPxColor := (ColorValue red: Red green: Green blue: Blue). edgedImage atPoint: x@y put: (newImage palette indexOfPaintNearest: newPxColor). ]. ]. edgedImage inspect.
とりあえずはまず4方向のラプラシアンです。8方向にもすぐに変更できると思います。