Skadron Prize 2015 in Computational Physics   “1234or5?”

The goal: Write a single Mathematica module that tries to recognize which of the five integers (1, 2, 3, 4 or 5) is displayed by a pixelated black and white image.  The unknown integer is represented by a given 80×80 matrix with either 0 (=black) and 1 (=white) as entries.  This matrix is a bitmap of the number’s original binary image, that was resized, rotated, shifted and also partially randomized.  When graphed, it is rather easy for the human eye (or better,  for the attached brain) to determine, which of the five integers is displayed.  This task can be more difficult for your number recognition code. The five original (undistorted) matrices are provided and can be used by your code. 

                                     

For example, after resizing, rotation, shift and addition of noise the given distorted image could look like this

                                     

Rules:   Your code will be tested with at least 50 randomly chosen images with slowly increasing degrees of distortion. The first set of images will be the completely undistorted (= original) ones.  The next set might just contain a small amount of noise, but no resizing, rotation or shift. Please do not be discouraged, it is extremely difficult to find a perfect algorithm that can recognize an image that has been destroyed based on all four distortion operations.  At the end, the module that can identify the most images correctly wins.  Please note that your module should be able to guess the 50 integers in less than 10 cpu minutes.  You just have to write a module for a single image while the main tournament code will call it automatically 50 times.

The code:  Email a request for the actual tournament code to  grobe@ilstu.edu  and you can then easily modify the module  “MyName1” to implement your algorithm and test it. There are two input variables that you can use and one required output variable for your module:

	ORIGINALS  	A input list containing the five original 80×80 matrices.  These are the bitmaps of the original five integers.  For example, 
			ORIGINAL[[4]] is a matrix of the symbol “4”, where all 6400 matrix elements are either 0 (=black pixel) or 1 (=white pixel) 
	DISTORT	An input 80×80 matrix (with values zero or 1) that is the distorted bitmap of the unknown integer to be determined
	GUESS	An output integer variable with numerical values either 1, 2, 3, 4 or 5 to represent your guess of the number
	
You can immediately run the complete code by typing “⌘a”  (to select all Mathematica cells) and then ⇧⏎ (or ⌤ to run all cells).  At the end, I only need from you a single module that produces as your output a single integer  (to be either 1, 2, 3, 4 or 5).  A truly ingenious code that can actually determine about 20% of all images correctly could look like this: 
 
MyName1[ORIGINALS_, DISTORT_] := Module[{GUESS},
GUESS = RandomChoice[{1, 2, 3, 4, 5}];
GUESS]

Deadline: Please email your Mathematica module called “MyName1” as an attachment to  grobe@ilstu.edu    by  4pm Friday, April 10th.
 
Prize: The winner (or winning team) will be announced at our annual Physics Banquet (Bone Center Circus room on April 16th at 11am) and receive a check for $200.  The second prize will be $100.  For a list of the winners since 1998, see http://www.physics.illinoisstate.edu/undergrad/scholarships/skadron.shtml#prize.

Here is your own module (please modify this)

MyName1[ORIGINALS_, DISTORT_] := Module[{GUESS},
GUESS= RandomChoice[{1, 2, 3, 4, 5}];
GUESS]

Collection of modules (no need to open or look at this)

Kaputt[dim_,angle_,shiftd_,dims_,degreerand_, image_] :=Module[{rdmat},
(* Resizing of the image *)
rsimage=Resizeme[dims,dim, image] ;
(* Rotation of the image *)
rimage=Rotation[angle,dim,rsimage] ;
(* Shift of the image *)
mat=ImageData[ImageResize[rimage,{dim,dim}]]; 
smat=Schiebmich[shiftd,dim, mat] ;
(* Randomization of the matrix *)
rdmat=Randomization[degreerand,dim, smat] ;
rdmat]

Collection of the four distortion modules

Resizing of image

Resizeme[dims_, dim_,image_] :=Module[{rsimage},
rsimage=ImageResize[ImageCrop[image,{dims,dims},Padding->White],{dim,dim}];
rsimage]

Rotation of image

Rotation[angle_,dim_, image_] :=Module[{rimage},
rimage=ImageResize[ImageRotate[image,-angle Degree,Background->White],{dim,dim}];
rimage]

Shift of matrix

Schiebmich[shiftd_,dim_, mat_] :=Module[{smat},
smatr=mat;
smatu=mat;
smatl=mat;
smatd=mat;
dir=RandomChoice[{"l","r","u","d"}];
Do[smatl[[i,j]]=mat[[i,j+shiftd]],{i,1,dim},{j,1,dim-shiftd}];
Do[smatl[[i,j]]=1,{i,1,dim},{j,dim-shiftd,dim}];

Do[smatu[[i,j]]=mat[[i+shiftd,j]],{i,1,dim-shiftd},{j,1,dim}];
Do[smatu[[i,j]]=1,{i,dim-shiftd,dim},{j,1,dim}];

Do[smatr[[i,j]]=mat[[i,j-shiftd]],{i,1,dim},{j,shiftd+1,dim}];
Do[smatr[[i,j]]=1,{i,1,dim},{j,1,shiftd+1}];

Do[smatd[[i,j]]=mat[[i-shiftd,j]],{i,shiftd+1,dim},{j,1,dim}];
Do[smatd[[i,j]]=1,{i,1,shiftd+1},{j,1,dim}];

If[dir=="r",smat=smatr];
If[dir=="u",smat=smatu];
If[dir=="l",smat=smatl];
If[dir=="d",smat=smatd];
smat]

Randomization of matrix

Randomization[degreeofrandomization_,dim_, matrix_] :=Module[{rmatrix},
rmatrix=matrix;
Do[ rmatrix[[RandomInteger[{1,dim}],RandomInteger[{1,dim}]]]=RandomInteger[{0,1}],{j,1,degreeofrandomization}];
rmatrix]

Main tournament code (no need to understand or modify this)
                (except changing the number of “trials”)

numbers={,,,,};    (* here are the jpeg images of the undistorted numbers *)
dim=80;                                              (* dimension of the matrix *)
ORIGINALS=Table[0 ,{n,1,5},{i,1,dim},{j,1,dim}];
Do[ORIGINALS[[n]]=ImageData[ImageResize[numbers[[n]],{dim,dim}]],{n,1,5}];
trials=4;  (* number of test images to be offered *) 
Wins=Table[0,{n,1,trials}]; (* record of how many images were guessed correctly *)

Do[       (* here we loop through different images *)
zahl= RandomChoice[{1, 2, 3, 4, 5}]; (* this is our random number to be guessed  *)

(*  The four distortion parameters, randomly chosen *)
dims=RandomInteger[{200,300}];                                               (* dims for resizing *)
angle=RandomInteger[{-30,30}];                                               (* Angle for rotation *)
shiftd=RandomInteger[{0,20}];                                                 (* Shift             *)
degreerand=RandomInteger[{0,5000}];                                   (* Amount of randomization *)

(* below you could (uncomment 4 lines) and choose specfic distortion parameters *)
(* no distortion corresponds to:  dims=200, angle =0, shiftd=0, degreerand =0 *)
(* the absolute max distortion is: dims=300, angle =30, shiftd=20, degreerand =5000 *) 
(*
dims=200;                                               (* dims for resizing *)
angle=0;                                               (* Angle for rotation *)
shiftd=0;                                                 (* Shift             *)
degreerand=0;                                        (* Amount of randomization *)
*)

(* Here the matrix for the number is distorted *)
image=numbers[[zahl]]; (* the image file for our number to be guessed  *)
rdmat=Kaputt[dim,angle,shiftd,dims,degreerand,image] ;

(* Here your own module is called to guess the right number *)
GUESS1=MyName1[ORIGINALS,rdmat];
Print["The module MyName1 guessed: ", GUESS1, "  the correct number was: ",zahl];
If[GUESS1==zahl,Speak["bingo"]];
If[GUESS1==zahl,Wins[[n]]=1,Wins[[n]]=0],
            {n,1,trials}]

Print[" "]
Print[Style["Final score:",FontSize->18,Orange]]
Print[" Out of ",trials," images, you got ", trials Mean[Wins]," correct"]
Print[" "]

(*  here is an image of the last image from the do loop *)
matoriginal=ImageData[ImageResize[image,{dim,dim}]];
g1=MatrixPlot[matoriginal,ColorFunction->(If[#==1,White,Black]&)];
g2=MatrixPlot[rdmat,ColorFunction->(If[#==1,White,Black]&)] ;
Print["Distortion parameters of last image were:"]
Print["dims=",dims," angle=",angle," shiftd=",shiftd," degreerand=",degreerand]
Print["    last original image        last distorted image "]
{g1,g2}