Median filter: Difference between revisions

Content added Content deleted
(Go solution)
Line 292: Line 292:
Usage:
Usage:
<lang GDL>Result = MEDIANF(ARRAY, WINDOW)</lang>
<lang GDL>Result = MEDIANF(ARRAY, WINDOW)</lang>
=={{header|Go}}==
Implemented with existing GetPx/SetPx functions at Grayscale image task. It could be sped up by putting code in the raster package, but if you're concerned about speed, you should implement one of the O(n) algorithms available.
<lang go>package main

// Files required to build supporting package raster are found in:
// * Bitmap
// * Grayscale image
// * Read a PPM file
// * Write a PPM file

import (
"fmt"
"raster"
)

var g0, g1 *raster.Grmap
var ko [][]int
var kc []uint16
var mid int

func init() {
// hard code box of 9 pixels
ko = [][]int{
{-1, -1}, {0, -1}, {1, -1},
{-1, 0}, {0, 0}, {1, 0},
{-1, 1}, {0, 1}, {1, 1}}
kc = make([]uint16, len(ko))
mid = len(ko) / 2
}

func main() {
// Example file used here is Lenna50.jpg from the task "Percentage
// difference between images" converted with with the command
// convert Lenna50.jpg -colorspace gray Lenna50.ppm
// It shows very obvious compression artifacts when viewed at higher
// zoom factors.
b, err := raster.ReadPpmFile("Lenna50.ppm")
if err != nil {
fmt.Println(err)
return
}
g0 = b.Grmap()
w, h := g0.Extent()
g1 = raster.NewGrmap(w, h)
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
g1.SetPx(x, y, median(x, y))
}
}
// side by side comparison with input file shows compression artifacts
// greatly smoothed over, although at some loss of contrast.
err = g1.Bitmap().WritePpmFile("median.ppm")
if err != nil {
fmt.Println(err)
}
}

func median(x, y int) uint16 {
var n int
// construct sorted list as pixels are read. insertion sort can't be
// beat for a small number of items, plus there would be lots of overhead
// just to get numbers in and out of a library sort routine.
for _, o := range ko {
// read a pixel of the kernel
c, ok := g0.GetPx(x+o[0], y+o[1])
if !ok {
continue
}
// insert it in sorted order
var i int
for ; i < n; i++ {
if c < kc[i] {
for j := n; j > i; j-- {
kc[j] = kc[j-1]
}
break
}
}
kc[i] = c
n++
}
// compute median from sorted list
switch {
case n == len(kc): // the usual case, pixel with complete neighborhood
return kc[mid]
case n%2 == 1: // edge case, odd number of pixels
return kc[n/2]
}
// else edge case, even number of pixels
m := n / 2
return (kc[m-1] + kc[m]) / 2
}</lang>


=={{header|J}}==
=={{header|J}}==