Initial data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 72d218235f
commit f23f22d71c
199087 changed files with 3378941 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Median_filter
note: Image processing

View file

@ -0,0 +1,4 @@
The median filter takes in the neighbourhood the median color (see [[wp:Median filter|Median filter]])
''(to test the function below, you can use these [[Read_ppm_file|input]] and [[Write_ppm_file|output]] solutions)''

View file

@ -0,0 +1,95 @@
INCLUDE "H6:LOADPPM5.ACT"
INCLUDE "D2:SORT.ACT" ;from the Action! Tool Kit
DEFINE HISTSIZE="256"
PROC PutBigPixel(INT x,y BYTE col)
IF x>=0 AND x<=79 AND y>=0 AND y<=47 THEN
y==LSH 2
col==RSH 4
IF col<0 THEN col=0
ELSEIF col>15 THEN col=15 FI
Color=col
Plot(x,y)
DrawTo(x,y+3)
FI
RETURN
PROC DrawImage(GrayImage POINTER image INT x,y)
INT i,j
BYTE c
FOR j=0 TO image.gh-1
DO
FOR i=0 TO image.gw-1
DO
c=GetGrayPixel(image,i,j)
PutBigPixel(x+i,y+j,c)
OD
OD
RETURN
INT FUNC Clamp(INT x,min,max)
IF x<min THEN
RETURN (min)
ELSEIF x>max THEN
RETURN (max)
FI
RETURN (x)
BYTE FUNC Median(BYTE ARRAY a BYTE len)
SortB(a,len,0)
len==RSH 1
RETURN (a(len))
PROC Median3x3(GrayImage POINTER src,dst)
INT x,y,i,j,ii,jj,index,sum
BYTE ARRAY arr(9)
BYTE c
FOR j=0 TO src.gh-1
DO
FOR i=0 TO src.gw-1
DO
sum=0 index=0
FOR jj=-1 TO 1
DO
y=Clamp(j+jj,0,src.gh-1)
FOR ii=-1 TO 1
DO
x=Clamp(i+ii,0,src.gw-1)
c=GetGrayPixel(src,x,y)
arr(index)=c
index==+1
OD
OD
c=Median(arr,9)
SetGrayPixel(dst,i,j,c)
OD
OD
RETURN
PROC Main()
BYTE CH=$02FC ;Internal hardware value for last key pressed
BYTE ARRAY dataIn(900),dataOut(900)
GrayImage in,out
INT size=[30],x,y
Put(125) PutE() ;clear the screen
InitGrayImage(in,size,size,dataIn)
InitGrayImage(out,size,size,dataOut)
PrintE("Loading source image...")
LoadPPM5(in,"H6:LENA30G.PPM")
PrintE("Median filter...")
Median3x3(in,out)
Graphics(9)
x=(40-size)/2
y=(48-size)/2
DrawImage(in,x,y)
DrawImage(out,x+40,y)
DO UNTIL CH#$FF OD
CH=$FF
RETURN

View file

@ -0,0 +1,60 @@
function Median (Picture : Image; Radius : Positive) return Image is
type Extended_Luminance is range 0..10_000_000;
type VRGB is record
Color : Pixel;
Value : Luminance;
end record;
Width : constant Positive := 2*Radius*(Radius+1);
type Window is array (-Width..Width) of VRGB;
Sorted : Window;
Next : Integer;
procedure Put (Color : Pixel) is -- Sort using binary search
pragma Inline (Put);
This : constant Luminance :=
Luminance
( ( 2_126 * Extended_Luminance (Color.R)
+ 7_152 * Extended_Luminance (Color.G)
+ 722 * Extended_Luminance (Color.B)
)
/ 10_000
);
That : Luminance;
Low : Integer := Window'First;
High : Integer := Next - 1;
Middle : Integer := (Low + High) / 2;
begin
while Low <= High loop
That := Sorted (Middle).Value;
if That > This then
High := Middle - 1;
elsif That < This then
Low := Middle + 1;
else
exit;
end if;
Middle := (Low + High) / 2;
end loop;
Sorted (Middle + 1..Next) := Sorted (Middle..Next - 1);
Sorted (Middle) := (Color, This);
Next := Next + 1;
end Put;
Result : Image (Picture'Range (1), Picture'Range (2));
begin
for I in Picture'Range (1) loop
for J in Picture'Range (2) loop
Next := Window'First;
for X in I - Radius .. I + Radius loop
for Y in J - Radius .. J + Radius loop
Put
( Picture
( Integer'Min (Picture'Last (1), Integer'Max (Picture'First (1), X)),
Integer'Min (Picture'Last (2), Integer'Max (Picture'First (2), Y))
) );
end loop;
end loop;
Result (I, J) := Sorted (0).Color;
end loop;
end loop;
return Result;
end Median;

View file

@ -0,0 +1,7 @@
F1, F2 : File_Type;
begin
Open (F1, In_File, "city.ppm");
Create (F2, Out_File, "city_median.ppm");
Put_PPM (F2, Median (Get_PPM (F1), 1)); -- Window 3x3
Close (F1);
Close (F2);

View file

@ -0,0 +1,41 @@
INSTALL @lib$+"SORTLIB"
Sort% = FN_sortinit(0,0)
Width% = 200
Height% = 200
DIM out&(Width%-1, Height%-1)
VDU 23,22,Width%;Height%;8,16,16,128
*DISPLAY Lenagrey
OFF
REM Do the median filtering:
DIM pix&(24)
C% = 25
FOR Y% = 2 TO Height%-3
FOR X% = 2 TO Width%-3
P% = 0
FOR I% = -2 TO 2
FOR J% = -2 TO 2
pix&(P%) = TINT((X%+I%)*2, (Y%+J%)*2) AND &FF
P% += 1
NEXT
NEXT
CALL Sort%, pix&(0)
out&(X%, Y%) = pix&(12)
NEXT
NEXT Y%
REM Display:
GCOL 1
FOR Y% = 0 TO Height%-1
FOR X% = 0 TO Width%-1
COLOUR 1, out&(X%,Y%), out&(X%,Y%), out&(X%,Y%)
LINE X%*2,Y%*2,X%*2,Y%*2
NEXT
NEXT Y%
REPEAT
WAIT 1
UNTIL FALSE

View file

@ -0,0 +1,171 @@
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
typedef struct { unsigned char r, g, b; } rgb_t;
typedef struct {
int w, h;
rgb_t **pix;
} image_t, *image;
typedef struct {
int r[256], g[256], b[256];
int n;
} color_histo_t;
int write_ppm(image im, char *fn)
{
FILE *fp = fopen(fn, "w");
if (!fp) return 0;
fprintf(fp, "P6\n%d %d\n255\n", im->w, im->h);
fwrite(im->pix[0], 1, sizeof(rgb_t) * im->w * im->h, fp);
fclose(fp);
return 1;
}
image img_new(int w, int h)
{
int i;
image im = malloc(sizeof(image_t) + h * sizeof(rgb_t*)
+ sizeof(rgb_t) * w * h);
im->w = w; im->h = h;
im->pix = (rgb_t**)(im + 1);
for (im->pix[0] = (rgb_t*)(im->pix + h), i = 1; i < h; i++)
im->pix[i] = im->pix[i - 1] + w;
return im;
}
int read_num(FILE *f)
{
int n;
while (!fscanf(f, "%d ", &n)) {
if ((n = fgetc(f)) == '#') {
while ((n = fgetc(f)) != '\n')
if (n == EOF) break;
if (n == '\n') continue;
} else return 0;
}
return n;
}
image read_ppm(char *fn)
{
FILE *fp = fopen(fn, "r");
int w, h, maxval;
image im = 0;
if (!fp) return 0;
if (fgetc(fp) != 'P' || fgetc(fp) != '6' || !isspace(fgetc(fp)))
goto bail;
w = read_num(fp);
h = read_num(fp);
maxval = read_num(fp);
if (!w || !h || !maxval) goto bail;
im = img_new(w, h);
fread(im->pix[0], 1, sizeof(rgb_t) * w * h, fp);
bail:
if (fp) fclose(fp);
return im;
}
void del_pixels(image im, int row, int col, int size, color_histo_t *h)
{
int i;
rgb_t *pix;
if (col < 0 || col >= im->w) return;
for (i = row - size; i <= row + size && i < im->h; i++) {
if (i < 0) continue;
pix = im->pix[i] + col;
h->r[pix->r]--;
h->g[pix->g]--;
h->b[pix->b]--;
h->n--;
}
}
void add_pixels(image im, int row, int col, int size, color_histo_t *h)
{
int i;
rgb_t *pix;
if (col < 0 || col >= im->w) return;
for (i = row - size; i <= row + size && i < im->h; i++) {
if (i < 0) continue;
pix = im->pix[i] + col;
h->r[pix->r]++;
h->g[pix->g]++;
h->b[pix->b]++;
h->n++;
}
}
void init_histo(image im, int row, int size, color_histo_t*h)
{
int j;
memset(h, 0, sizeof(color_histo_t));
for (j = 0; j < size && j < im->w; j++)
add_pixels(im, row, j, size, h);
}
int median(const int *x, int n)
{
int i;
for (n /= 2, i = 0; i < 256 && (n -= x[i]) > 0; i++);
return i;
}
void median_color(rgb_t *pix, const color_histo_t *h)
{
pix->r = median(h->r, h->n);
pix->g = median(h->g, h->n);
pix->b = median(h->b, h->n);
}
image median_filter(image in, int size)
{
int row, col;
image out = img_new(in->w, in->h);
color_histo_t h;
for (row = 0; row < in->h; row ++) {
for (col = 0; col < in->w; col++) {
if (!col) init_histo(in, row, size, &h);
else {
del_pixels(in, row, col - size, size, &h);
add_pixels(in, row, col + size, size, &h);
}
median_color(out->pix[row] + col, &h);
}
}
return out;
}
int main(int c, char **v)
{
int size;
image in, out;
if (c <= 3) {
printf("Usage: %s size ppm_in ppm_out\n", v[0]);
return 0;
}
size = atoi(v[1]);
printf("filter size %d\n", size);
if (size < 0) size = 1;
in = read_ppm(v[2]);
out = median_filter(in, size);
write_ppm(out, v[3]);
free(in);
free(out);
return 0;
}

View file

@ -0,0 +1,76 @@
import grayscale_image;
Image!Color medianFilter(uint radius=10, Color)(in Image!Color img)
pure nothrow @safe if (radius > 0) in {
assert(img.nx >= radius && img.ny >= radius);
} body {
alias Hist = uint[256];
static ubyte median(uint no)(in ref Hist cumulative)
pure nothrow @safe @nogc {
size_t localSum = 0;
foreach (immutable k, immutable v; cumulative)
if (v) {
localSum += v;
if (localSum > no / 2)
return k;
}
return 0;
}
// Copy image borders in the result image.
auto result = new Image!Color(img.nx, img.ny);
foreach (immutable y; 0 .. img.ny)
foreach (immutable x; 0 .. img.nx)
if (x < radius || x > img.nx - radius - 1 ||
y < radius || y > img.ny - radius - 1)
result[x, y] = img[x, y];
enum edge = 2 * radius + 1;
auto hCol = new Hist[img.nx];
// Create histogram columns.
foreach (immutable y; 0 .. edge - 1)
foreach (immutable x, ref hx; hCol)
hx[img[x, y]]++;
foreach (immutable y; radius .. img.ny - radius) {
// Add to each histogram column lower pixel.
foreach (immutable x, ref hx; hCol)
hx[img[x, y + radius]]++;
// Calculate main Histogram using first edge-1 columns.
Hist H;
foreach (immutable x; 0 .. edge - 1)
foreach (immutable k, immutable v; hCol[x])
if (v)
H[k] += v;
foreach (immutable x; radius .. img.nx - radius) {
// Add right-most column.
foreach (immutable k, immutable v; hCol[x + radius])
if (v)
H[k] += v;
result[x, y] = Color(median!(edge ^^ 2)(H));
// Drop left-most column.
foreach (immutable k, immutable v; hCol[x - radius])
if (v)
H[k] -= v;
}
// Substract the upper pixels.
foreach (immutable x, ref hx; hCol)
hx[img[x, y - radius]]--;
}
return result;
}
version (median_filter_main)
void main() { // Demo.
loadPGM!Gray(null, "lena.pgm").
medianFilter!10
.savePGM("lena_median_r10.pgm");
}

View file

@ -0,0 +1,117 @@
{-------------------------------------------------------------------------------}
type THistogram = record
Bins: array [0..255] of integer;
Colors: array [0..255] of TRGBTriple;
end;
procedure MedianFilter(Src,Dest: TBitmap; WindowX, WindowY: integer);
var x, y, X1, Y1, med, md, dl, delta_l, WX2, WY2: integer;
var I, MedSum, XStart,XEnd, YStart,YEnd, MedInx: integer;
var middle: integer;
var Histogram: THistogram;
var u: byte;
var Color: TRGBTriple;
var SrcRows,DestRows: TRGBTripleRowArray;
begin
WindowX:=WindowX * 2 -1;
WindowY:=WindowY * 2 -1;
Src.PixelFormat:=pf24Bit;
Dest.PixelFormat:=pf24Bit;
Dest.Width:=Src.Width;
Dest.Height:=Src.Height;
SetLength(SrcRows,Src.Height);
SetLength(DestRows,Dest.Height);
{Capture scan lines of both source and destiantion bitmaps}
for Y:=0 to Src.Height-1 do SrcRows[Y]:=Src.ScanLine[Y];
for Y:=0 to Dest.Height-1 do DestRows[Y]:=Dest.ScanLine[Y];
WX2 := WindowX div 2;
WY2 := WindowY div 2;
middle := (WindowX * WindowY-1) div 2;
for y := 0 to SRC.Height-1 do
begin
{ Determine the histogram and median for the first element of each row}
YStart:=Y - WY2;
YEnd:=Y + WY2;
{ histogram reset }
for I := 0 to 255 do Histogram.Bins[I] := 0;
{recalculation of the histogram for the start element row=y, col=0 }
for Y1 := YStart to YEnd do
for X1 := -WX2 to WX2 do
begin
{It is the first pixel on the row, so don't worry about right edge}
if (Y1>=0) and (Y1<SRC.Height) and (X1>=0) then Color:=SrcRows[Y1][X1] else Color:=MakeRBGTriple(0,0,0); // Color:=SrcRows[y][0];
U:=RGBToGray(Color);
inc(Histogram.Bins[U]);
Histogram.Colors[U]:=Color;
end;
{ now determine the median }
MedSum := 0;
for MedInx := 0 to 255 do
begin
inc(MedSum,Histogram.Bins[MedInx]);
if MedSum > middle then break;
end;
med := MedInx;
delta_l := MedSum - Histogram.Bins[MedInx];
DestRows[Y][0]:=Histogram.Colors[MedInx];
{ Loop through each column in this row}
for x := 1 to Src.Width-1 do
begin
XStart := x-wx2-1;
XEnd := x+wx2;
{ go to next column }
for Y1 := YStart to YEnd do
begin
if (XStart >= 0) and (Y1 >= 0) and (Y1 < SRC.Height) then Color:=SrcRows[Y1][XStart] else Color:=MakeRBGTriple(0,0,0); // Color:=SrcRows[Y][X];
U:=RGBToGray(Color);
if Histogram.Bins[u]>0 then dec(Histogram.Bins[u]);
if u < med then dec(delta_l);
if (XEnd < Src.Width) and (Y1 >= 0) and (Y1 < SRC.Height) then Color:=SrcRows[Y1][XEnd] else Color:=MakeRBGTriple(0,0,0); // Color:=SrcRows[Y][X];
U:=RGBToGray(Color);
inc(Histogram.Bins[u]);
Histogram.Colors[U]:=Color;
if u < med then inc(delta_l);
end;
{ update new median }
dl := delta_l;
md := med;
if dl > middle then
begin
while dl > middle do
begin
dec(md);
if Histogram.Bins[md] > 0 then
dec(dl,Histogram.Bins[md]);
end;
end
else
begin
while dl + Histogram.Bins[md] <= middle do
begin
if Histogram.Bins[md] > 0 then inc(dl,Histogram.Bins[md]);
inc(md);
end;
end;
delta_l := dl;
med := md;
DestRows[Y][X]:= Histogram.Colors[med];
end; { x loop}
end; { y loop}
end;

View file

@ -0,0 +1,90 @@
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
}

View file

@ -0,0 +1,2 @@
makeRGB=: 0&$: : (($,)~ ,&3)
toGray=: <. @: (+/) @: (0.2126 0.7152 0.0722 & *)"1

View file

@ -0,0 +1,9 @@
median_filter =: dyad define
win =. y -~ i. >: +: y
height =. {: }: $ x
width =. {. }: $ x
h_indexes =. < @ (#~ >:&0 * <&height) @ (win&+)"0 i. height
w_indexes =. < @ (#~ >:&0 * <&width) @ (win&+)"0 i. width
sets =. w_indexes < @ ({&x) @ < @ ,"0 0/ h_indexes
medians =. ({~ <. @ -: @ {. @ $) @ ({~ /: @: toGray) @ (,/) @ > sets
)

View file

@ -0,0 +1,48 @@
] bmp =. ?. 256 + makeRGB 4 5
34 39 168
133 133 40
210 137 244
66 183 114
211 241 75
212 68 13
91 246 128
203 236 213
162 92 165
90 203 161
104 124 113
199 61 60
135 179 241
142 156 125
64 77 61
130 70 200
114 32 55
94 211 182
29 49 252
116 139 217
bmp median_filter 1
133 133 40
210 137 244
210 137 244
90 203 161
90 203 161
104 124 113
133 133 40
66 183 114
210 137 244
66 183 114
212 68 13
104 124 113
142 156 125
142 156 125
116 139 217
130 70 200
104 124 113
142 156 125
142 156 125
116 139 217

View file

@ -0,0 +1,92 @@
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.imageio.ImageIO;
public final class MedianFilter {
public static void main(String[] aArgs) {
try {
BufferedImage image = ImageIO.read( new File("beforeFilter.png") );
BasicBitmapStorage bitmap = new BasicBitmapStorage(image.getWidth(null), image.getHeight(null));
for ( int y = 0; y < image.getHeight(null); y++ ) {
for ( int x = 0; x < image.getWidth(null); x++ ) {
bitmap.setPixel(x, y, new Color(image.getRGB(x, y), true));
}
}
bitmap.medianFilter(3, 3);
File fileAfterFilter = new File("afterFilter.png");
ImageIO.write((RenderedImage) bitmap.getImage(), "png", fileAfterFilter);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
final class BasicBitmapStorage {
public BasicBitmapStorage(int aWidth, int aHeight) {
image = new BufferedImage(aWidth, aHeight, BufferedImage.TYPE_INT_RGB);
}
public void fill(Color aColor) {
Graphics graphics = image.getGraphics();
graphics.setColor(aColor);
graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
}
public Color getPixel(int aX, int aY) {
return new Color(image.getRGB(aX, aY));
}
public void setPixel(int aX, int aY, Color aColor) {
image.setRGB(aX, aY, aColor.getRGB());
}
public Image getImage() {
return image;
}
public void medianFilter(int aWindowWidth, int aWindowHeight) {
List<Color> window = Stream.generate( () -> Color.BLACK )
.limit(aWindowWidth * aWindowHeight).collect(Collectors.toList());
final int edgeX = aWindowWidth / 2;
final int edgeY = aWindowHeight / 2;
Comparator<Color> luminanceComparator = (one, two) -> Double.compare(luminance(one), luminance(two));
for ( int x = edgeX; x < image.getWidth() - edgeX; x++ ) {
for ( int y = edgeY; y < image.getHeight() - edgeY; y++ ) {
int i = 0;
for ( int fx = 0; fx < aWindowWidth; fx++ ) {
for ( int fy = 0; fy < aWindowHeight; fy++ ) {
window.set(i, getPixel(x + fx - edgeX, y + fy - edgeY));
i += 1;
}
}
Collections.sort(window, luminanceComparator);
setPixel(x, y, window.get(aWindowWidth * aWindowHeight / 2));
}
}
}
private double luminance(Color aColor) {
return 0.2126 * aColor.getRed() + 0.7152 * aColor.getGreen() + 0.0722 * aColor.getBlue();
}
private final BufferedImage image;
}

View file

@ -0,0 +1,7 @@
using Images, ImageFiltering, FileIO
Base.isless(a::RGB{T}, b::RGB{T}) where T =
red(a) < red(b) || green(a) < green(b) || blue(a) < blue(b)
Base.middle(x::RGB) = x
img = load("data/lenna100.jpg")
mapwindow(median!, img, (3, 3))

View file

@ -0,0 +1,57 @@
// Version 1.2.41
import java.awt.Color
import java.awt.Graphics
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
class BasicBitmapStorage(width: Int, height: Int) {
val image = BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR)
fun fill(c: Color) {
val g = image.graphics
g.color = c
g.fillRect(0, 0, image.width, image.height)
}
fun setPixel(x: Int, y: Int, c: Color) = image.setRGB(x, y, c.getRGB())
fun getPixel(x: Int, y: Int) = Color(image.getRGB(x, y))
fun medianFilter(windowWidth: Int, windowHeight: Int) {
val window = Array(windowWidth * windowHeight) { Color.black }
val edgeX = windowWidth / 2
val edgeY = windowHeight / 2
val compareByLuminance = {
c: Color -> 0.2126 * c.red + 0.7152 * c.green + 0.0722 * c.blue
}
for (x in edgeX until image.width - edgeX) {
for (y in edgeY until image.height - edgeY) {
var i = 0
for (fx in 0 until windowWidth) {
for (fy in 0 until windowHeight) {
window[i] = getPixel(x + fx - edgeX, y + fy - edgeY)
i++
}
}
window.sortBy(compareByLuminance)
setPixel(x, y, window[windowWidth * windowHeight / 2])
}
}
}
}
fun main(args: Array<String>) {
val img = ImageIO.read(File("Medianfilterp.png"))
val bbs = BasicBitmapStorage(img.width / 2, img.height)
with (bbs) {
for (y in 0 until img.height) {
for (x in 0 until img.width / 2) {
setPixel(x, y, Color(img.getRGB(x, y)))
}
}
medianFilter(3, 3)
val mfFile = File("Medianfilterp2.png")
ImageIO.write(image, "png", mfFile)
}
}

View file

@ -0,0 +1 @@
MedianFilter[img,n]

View file

@ -0,0 +1,28 @@
import algorithm
import imageman
func luminance(color: ColorRGBF64): float =
0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b
proc applyMedianFilter(img: var Image; windowWidth, windowHeight: Positive) =
var window = newSeq[ColorRGBF64](windowWidth * windowHeight)
let edgeX = windowWidth div 2
let edgeY = windowHeight div 2
for x in edgeX..<(img.width - edgeX):
for y in edgeY..<(img.height - edgeY):
var i = 0
for fx in 0..<windowWidth:
for fy in 0..<windowHeight:
window[i] = img[x + fx - edgeX, y + fy - edgeY]
inc i
window = window.sortedByIt(luminance(it))
img[x, y] = window[windowWidth * windowHeight div 2]
when isMainModule:
let fullImage = loadImage[ColorRGBF64]("Medianfilterp.png")
# Extract left part of the image.
var image = fullImage[0..<(fullImage.width div 2), 0..<fullImage.height]
image.applyMedianFilter(3, 3)
savePNG(image, "Medianfilterp_3x3.png")

View file

@ -0,0 +1,64 @@
let color_add (r1,g1,b1) (r2,g2,b2) =
( (r1 + r2),
(g1 + g2),
(b1 + b2) )
let color_div (r,g,b) d =
( (r / d),
(g / d),
(b / d) )
let compare_as_grayscale (r1,g1,b1) (r2,g2,b2) =
let v1 = (2_126 * r1 + 7_152 * g1 + 722 * b1)
and v2 = (2_126 * r2 + 7_152 * g2 + 722 * b2) in
(Pervasives.compare v1 v2)
let get_rgb img x y =
let _, r_channel,_,_ = img in
let width = Bigarray.Array2.dim1 r_channel
and height = Bigarray.Array2.dim2 r_channel in
if (x < 0) || (x >= width) then (0,0,0) else
if (y < 0) || (y >= height) then (0,0,0) else (* feed borders with black *)
(get_pixel img x y)
let median_value img radius =
let samples = (radius*2+1) * (radius*2+1) in
fun x y ->
let sample = ref [] in
for _x = (x - radius) to (x + radius) do
for _y = (y - radius) to (y + radius) do
let v = get_rgb img _x _y in
sample := v :: !sample;
done;
done;
let ssample = List.sort compare_as_grayscale !sample in
let mid = (samples / 2) in
if (samples mod 2) = 1
then List.nth ssample (mid+1)
else
let median1 = List.nth ssample (mid)
and median2 = List.nth ssample (mid+1) in
(color_div (color_add median1 median2) 2)
let median img radius =
let _, r_channel,_,_ = img in
let width = Bigarray.Array2.dim1 r_channel
and height = Bigarray.Array2.dim2 r_channel in
let _median_value = median_value img radius in
let res = new_img ~width ~height in
for y = 0 to pred height do
for x = 0 to pred width do
let color = _median_value x y in
put_pixel res color x y;
done;
done;
(res)

View file

@ -0,0 +1,20 @@
let median_value img radius =
let samples = (radius*2+1) * (radius*2+1) in
let sample = Array.make samples (0,0,0) in
fun x y ->
let i = ref 0 in
for _x = (x - radius) to (x + radius) do
for _y = (y - radius) to (y + radius) do
let v = get_rgb img _x _y in
sample.(!i) <- v;
incr i;
done;
done;
Array.sort compare_as_grayscale sample;
let mid = (samples / 2) in
if (samples mod 2) = 1
then sample.(mid+1)
else (color_div (color_add sample.(mid)
sample.(mid+1)) 2)

View file

@ -0,0 +1,9 @@
use strict 'vars';
use warnings;
use PDL;
use PDL::Image2D;
my $image = rpic 'plasma.png';
my $smoothed = med2d $image, ones(3,3), {Boundary => Truncate};
wpic $smoothed, 'plasma_median.png';

View file

@ -0,0 +1,51 @@
-- demo\rosetta\Bitmap_Median_filter.exw
include ppm.e
constant neigh = {{-1,-1},{0,-1},{1,-1},
{-1, 0},{0, 0},{1, 0},
{-1, 1},{0, 1},{1, 1}}
--constant neigh = {{-2,-2},{-1,-2},{0,-2},{1,-2},{2,-2},
-- {-2,-1},{-1,-1},{0,-1},{1,-1},{2,-1},
-- {-2, 0},{-1, 0},{0, 0},{1, 0},{2, 0},
-- {-2, 1},{-1, 1},{0, 1},{1, 1},{2, 1},
-- {-2, 2},{-1, 2},{0, 2},{1, 2},{2, 2}}
sequence kn = repeat(0,length(neigh))
function median(sequence image)
integer h = length(image),
w = length(image[1])
for i=1 to length(image) do
for j=1 to length(image[i]) do
integer n = 0, c, p, x, y
for k=1 to length(neigh) do
x = i+neigh[k][1]
y = j+neigh[k][2]
if x>=1 and x<=h
and y>=1 and y<=w then
n += 1
c = image[x,j]
p = n
while p>1 do
if c>kn[p-1] then exit end if
kn[p] = kn[p-1]
p -= 1
end while
kn[p] = c
end if
end for
if and_bits(n,1) then
c = kn[(n+1)/2]
else
c = floor((kn[n/2]+kn[n/2+1])/2)
end if
image[i,j] = c
end for
end for
return image
end function
sequence img = read_ppm("Lena.ppm")
img = median(img)
write_ppm("LenaMedian.ppm",img)

View file

@ -0,0 +1,31 @@
(de ppmMedianFilter (Radius Ppm)
(let Len (inc (* 2 Radius))
(make
(chain (head Radius Ppm))
(for (Y Ppm T (cdr Y))
(NIL (nth Y Len)
(chain (tail Radius Y)) )
(link
(make
(chain (head Radius (get Y (inc Radius))))
(for (X (head Len Y) T)
(NIL (nth X 1 Len)
(chain (tail Radius (get X (inc Radius)))) )
(link
(cdr
(get
(sort
(mapcan
'((Y)
(mapcar
'((C)
(cons
(+
(* (car C) 2126) # Red
(* (cadr C) 7152) # Green
(* (caddr C) 722) ) # Blue
C ) )
(head Len Y) ) )
X ) )
(inc Radius) ) ) )
(map pop X) ) ) ) ) ) ) )

View file

@ -0,0 +1,5 @@
import Image, ImageFilter
im = Image.open('image.ppm')
median = im.filter(ImageFilter.MedianFilter(3))
median.save('image2.ppm')

View file

@ -0,0 +1,21 @@
#lang racket
(require images/flomap math)
(define lena <<paste image of Lena here>> )
(define bm (send lena get-bitmap))
(define fm (bitmap->flomap bm))
(flomap->bitmap
(build-flomap
4 (send bm get-width) (send bm get-height)
(λ (k x y)
(define (f x y) (flomap-ref fm k x y))
(median < (list (f (- x 1) (- y 1))
(f (- x 1) y)
(f (- x 1) (+ y 1))
(f x (- y 1))
(f x y)
(f x (+ y 1))
(f (+ x 1) (- y 1))
(f (+ x 1) y)
(f (+ x 1) (+ y 1)))))))

View file

@ -0,0 +1,6 @@
use PDL:from<Perl5>;
use PDL::Image2D:from<Perl5>;
my $image = rpic 'plasma.png';
my $smoothed = med2d($image, ones(3,3), {Boundary => 'Truncate'});
wpic $smoothed, 'plasma_median.png';

View file

@ -0,0 +1,67 @@
class Pixmap
def median_filter(radius=3)
radius += 1 if radius.even?
filtered = self.class.new(@width, @height)
pb = ProgressBar.new(@height) if $DEBUG
@height.times do |y|
@width.times do |x|
window = []
(x - radius).upto(x + radius).each do |win_x|
(y - radius).upto(y + radius).each do |win_y|
win_x = 0 if win_x < 0
win_y = 0 if win_y < 0
win_x = @width-1 if win_x >= @width
win_y = @height-1 if win_y >= @height
window << self[win_x, win_y]
end
end
# median
filtered[x, y] = window.sort[window.length / 2]
end
pb.update(y) if $DEBUG
end
pb.close if $DEBUG
filtered
end
end
class RGBColour
# refactoring
def luminosity
Integer(0.2126*@red + 0.7152*@green + 0.0722*@blue)
end
def to_grayscale
l = luminosity
self.class.new(l, l, l)
end
# defines how to compare (and hence, sort)
def <=>(other)
self.luminosity <=> other.luminosity
end
end
class ProgressBar
def initialize(max)
$stdout.sync = true
@progress_max = max
@progress_pos = 0
@progress_view = 68
$stdout.print "[#{'-'*@progress_view}]\r["
end
def update(n)
new_pos = n * @progress_view/@progress_max
if new_pos > @progress_pos
@progress_pos = new_pos
$stdout.print '='
end
end
def close
$stdout.puts '=]'
end
end
bitmap = Pixmap.open('file')
filtered = bitmap.median_filter

View file

@ -0,0 +1,47 @@
package require Tk
# Set the color of a pixel
proc applyMedian {srcImage x y -> dstImage} {
set x0 [expr {$x==0 ? 0 : $x-1}]
set y0 [expr {$y==0 ? 0 : $y-1}]
set x1 $x
set y1 $y
set x2 [expr {$x+1==[image width $srcImage] ? $x : $x+1}]
set y2 [expr {$y+1==[image height $srcImage] ? $y : $y+1}]
set r [set g [set b {}]]
foreach X [list $x0 $x1 $x2] {
foreach Y [list $y0 $y1 $y2] {
lassign [$srcImage get $X $Y] rPix gPix bPix
lappend r $rPix
lappend g $gPix
lappend b $bPix
}
}
set r [lindex [lsort -integer $r] 4]
set g [lindex [lsort -integer $g] 4]
set b [lindex [lsort -integer $b] 4]
$dstImage put [format "#%02x%02x%02x" $r $g $b] -to $x $y
}
# Apply the filter to the whole image
proc medianFilter {srcImage {dstImage ""}} {
if {$dstImage eq ""} {
set dstImage [image create photo]
}
set w [image width $srcImage]
set h [image height $srcImage]
for {set x 0} {$x < $w} {incr x} {
for {set y 0} {$y < $h} {incr y} {
applyMedian $srcImage $x $y -> $dstImage
}
}
return $dstImage
}
# Demonstration code using the Tk widget demo's teapot image
image create photo teapot -file $tk_library/demos/images/teapot.ppm
pack [labelframe .src -text Source] -side left
pack [label .src.l -image teapot]
update
pack [labelframe .dst -text Median] -side left
pack [label .dst.l -image [medianFilter teapot]]

View file

@ -0,0 +1,57 @@
import "graphics" for Canvas, ImageData, Color
import "dome" for Window
class MedianFilter {
construct new(filename, filename2, windowWidth, windowHeight) {
Window.title = "Median filter"
var image = ImageData.loadFromFile(filename)
Window.resize(image.width, image.height)
Canvas.resize(image.width, image.height)
_ww = windowWidth
_wh = windowHeight
// split off the left half
_image = ImageData.create(filename2, image.width/2, image.height)
_name = filename2
for (x in 0...image.width/2) {
for (y in 0...image.height) _image.pset(x, y, image.pget(x, y))
}
// display it on the left before filtering
_image.draw(0, 0)
}
luminance(c) { 0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b }
medianFilter(windowWidth, windowHeight) {
var window = List.filled(windowWidth * windowHeight, Color.black)
var edgeX = (windowWidth / 2).floor
var edgeY = (windowHeight / 2).floor
var comparer = Fn.new { |a, b| luminance(a) < luminance(b) }
for (x in edgeX..._image.width - edgeX) {
for (y in edgeY..._image.height - edgeY) {
var i = 0
for (fx in 0...windowWidth) {
for (fy in 0...windowHeight) {
window[i] = _image.pget(x + fx - edgeX, y + fy - edgeY)
i = i + 1
}
}
window.sort(comparer)
_image.pset(x, y, window[((windowWidth * windowHeight)/2).floor])
}
}
}
init() {
medianFilter(_ww, _wh)
// display it on the right after filtering
_image.draw(_image.width, 0)
// save it to a file
_image.saveToFile(_name)
}
update() {}
draw(alpha) {}
}
var Game = MedianFilter.new("Medianfilterp.png", "Medianfilterp2.png", 3, 3)

View file

@ -0,0 +1,14 @@
fcn medianFilter(img){ //-->new image
var [const] window=[-2..2].walk(), edge=(window.len()/2); // 5x5 window
MX,MY,new := img.w,img.h,PPM(MX,MY);
pixel,pixels:=List(),List();
foreach x,y in ([edge..MX-edge-1],[edge..MY-edge-1]){
pixels.clear();
foreach ox,oy in (window,window){ // construct sorted list as pixels are read.
pixels.merge(pixel.clear(img[x+ox, y+oy])); // merge sort two lists
}
new[x,y]=pixels[4]; // median value
}
new
}

View file

@ -0,0 +1,2 @@
filtered:=medianFilter(PPM.readJPGFile("lena.jpg"));
filtered.writeJPGFile("lenaMedianFiltered.zkl.jpg");