Mathematica 9 is now available
Student Support Forum
-----
Student Support Forum: 'Rotate Image' topicStudent Support Forum > General > "Rotate Image"

Help | Reply To Topic
Author Comment/Response
Student
03/29/09 11:30pm

Derotate[img_] :=
Module[{r, c, pairs, theFit, a, b, angle, rotator, newString,
shiftedString, rotated, row, col, newImage1, newImage2, newImage3,
across, down},
(*We want to pull only the black portions out of the image.
The For loop
scans for any pixel less than value 100 so we pull out only the \
black pixels.
*)
{r, c} = Dimensions[img]; pairs = {};
For[i = 1, i <= r, i++,
For[j = 1, j <= c, j++,
If[img[[i, j]] <= 100, pairs = Append[pairs, {j, i}]];
];(*End row loop*)
];(*End column loop*)
(*

As a crude method of finding the rotation angle of the angle,
we treat the pixels as {x,y} pairs and perfrom a linear regression
Then we take the arctan of the slope to find the angle. Then we plug
the angle into a rotator matrix and transform our values.
Since we are
plugging them back into a matrix, we need to round the values.
*)
theFit = {a, b} /. FindFit[pairs, a x + b, {a, b}, x];
angle = ArcTan[First[theFit]];
rotator = {{Cos[angle], Sin[angle]}, {-Sin[angle], Cos[angle]}};(*
Rotation Matrix *)
R[coords_] := rotator.coords;
newString = Round[R /@ pairs]; (*
Returns rotated coordinate pairs *)
(*

In order to simply the procedure of repopulating our image matrix
we shift all the row and column points to an origin of {1,1}. Then
we transpose the shifted matrix into {x,y} pairs.
*)
shiftedString = Transpose[newString];
shiftedString[[1]] =
shiftedString[[1]] - Min[First[shiftedString] - 1];
shiftedString[[2]] =
shiftedString[[2]] - Min[Last[shiftedString] - 1];
rotated = Transpose[shiftedString];
{row, col} = {Max[Last[shiftedString]] -
Min[Last[shiftedString]] + 1,
Max[First[shiftedString]] - Min[First[shiftedString]] + 1};
newImage = ConstantArray[0, {row, col}] + 255;

(*
Now we create a zero matrix and populate it with zeros at \
the new
coordinates produced by the rotation transform.
*)

For[i = 1, i <= Length[rotated], i++,
newImage = ReplacePart[newImage, 0, Reverse[rotated[[i]]]];
];(*End column loop*)

(*
Interpolate between empty pixels in the columns.
If a white pixel is surrounded by two
black pixels we change it to a black pixel.
*)
newImage1 = {}; For[j = 1, j <= col, j++,
across = Flatten[TakeColumns[newImage, {j, j}]];
For[i = 2, i <= Length[across] - 1, i++,
If[across[[i]] == 255 && across[[i - 1]] == 0 &&
across[[i + 1]] == 0, across[[i]] = 0;
];
];
newImage1 = Append[newImage1, across];]; newImage2 = {};
For[k = 1, k <= row, k++,
down = Flatten[TakeRows[Transpose[newImage1], {k, k}]];
For[p = 2, p <= Length[down] - 1, p++,
If[down[[i]] == 255 && down[[i - 1]] == 0 && down[[i + 1]] == 0,
down[[i]] = 0;
];
];
(*
Same as above, except work across the rows
*)
newImage2 = Append[newImage2, down];
];
(* Pad the matrix *)

newImage3 =
AppendColumns[ConstantArray[0, {1, col}] + 255, newImage2,
ConstantArray[0, {1, col}] + 255]; Return[pairs];];
img = ImageRead["/Users/username/Desktop/coursenumber/CAPTCHA/R.bmp",
PrintInfo -> True];

The dimensions of the image are 437 x
732 and the file was processed as a color image. A total of
0 iterations of a wavelet transform can be performed
on the image.


ImagePlot[img];
ListPlot[Derotate[img]]

Set::shape: Lists {r$1311,c$1311} and {3,437,732} are not the same shape. >>

Transpose::nmtx: The first two levels of the one-dimensional list {} cannot be transposed. >>

Transpose::nmtx: The first two levels of the one-dimensional list {} cannot be transposed. >>

Part::partw: Part 2 of Transpose[{}] does not exist. >>

Set::partw: Part 2 of Transpose[{}] does not exist. >>

ConstantArray::ilsmn: Single or list of non-negative machine-size integers expected at position 2 of ConstantArray[0,{-\[Infinity],-\[Infinity]}]. >>

Transpose::nmtx: The first two levels of the one-dimensional list {} cannot be transposed. >>

General::stop: Further output of Transpose::nmtx will be suppressed during this calculation. >>

ReplacePart::psl: Position specification Transpose[{}] in ReplacePart[255+ConstantArray[0,{-\[Infinity],-\[Infinity]}],0,Transpose[{}]] is not an integer or a list of integers. >>

ConstantArray::ilsmn: Single or list of non-negative machine-size integers expected at position 2 of ConstantArray[0,{1,-\[Infinity]}]. >>

ConstantArray::ilsmn: Single or list of non-negative machine-size integers expected at position 2 of ConstantArray[0,{1,-\[Infinity]}]. >>

General::stop: Further output of ConstantArray::ilsmn will be suppressed during this calculation. >>

ListPlot::lpn: {{}} is not a list of numbers or pairs of numbers. >>

ListPlot[{}]

Does anyone understand why I obtain these errors?

Attachment: rotationtest.nb, URL: ,
Help | Reply To Topic