Image rotation


#1

Hi All,

I can’t find an analog for Matlab “imrotate” function.
Maybe I overlooked it, or really there isn’t such thing?

Here it is in Matlab, to save you clicking:

imrotate Rotate image.
    B = imrotate(A,ANGLE) rotates image A by ANGLE degrees in a
    counterclockwise direction around its center point. To rotate the image
    clockwise, specify a negative value for ANGLE. imrotate makes the output
    image B large enough to contain the entire rotated image. imrotate uses
    nearest neighbor interpolation, setting the values of pixels in B that
    are outside the rotated image to 0 (zero).
 
    B = imrotate(A,ANGLE,METHOD) rotates image A, using the interpolation
    method specified by METHOD. METHOD is a string that can have one of the
    following values. The default value is enclosed in braces ({}).
 
         {'nearest'}  Nearest neighbor interpolation
 
         'bilinear'   Bilinear interpolation
 
         'bicubic'    Bicubic interpolation. Note: This interpolation
                      method can produce pixel values outside the original
                      range.
 
    B = imrotate(A,ANGLE,METHOD,BBOX) rotates image A, where BBOX specifies
    the size of the output image B. BBOX is a text string that can have
    either of the following values. The default value is enclosed in braces
    ({}).
 
         {'loose'}    Make output image B large enough to contain the
                      entire rotated image. B is generally larger than A.
 
         'crop'       Make output image B the same size as the input image
                      A, cropping the rotated image to fit.

#2

Use warp from ImageTransformations. But I see it’s missing a docstring…I’ll fix that and publish a new version today.


#3

great thank you, I’ll try.

some unrelated stuff - translating from Matlab, I struggle with couple of syntactic trivia.
First is thresholding, like here in Matlab:

>> x = [ 1 3 78 98 11];
>> y=x>60

y =

  1×5 logical array

   0   0   1   1   0

another one, how to initiate array by NaNs.
Julia:

> NaN(10)
x MethodError: objects of type Float64 are not callable

certainly can write local functions, but that’s clumsy, if language allows, it would be great to know.
sorry for nuisance.


#4

You can use dot-operators like .> in Julia for your first question:

julia> x = [1 3 78 98 11]
1×5 Array{Int64,2}:
 1  3  78  98  11

julia> y = x .> 60
1×5 BitArray{2}:
 false  false  true  true  false

julia> x[y]
2-element Array{Int64,1}:
 78
 98

and fill() for your second question:

julia> fill(NaN, 10, 10)

#5

You can read the new docstring here; not merged yet because, for something really robust, there’s work to do in Interpolations.jl, and I may not get to it instantly. But it should be good enough to get you started.


#6

thanks very much both!
I will check “warp” and let know, if it performs as expected.


#7

Great, the transform works, however i didn’t find how to extract correctly the central part in the resulting image. So I did it manually.

As I need only a rotation about center, I wrote the following helper to cut it shorter:

###################################
# rotate image "I" around its centre by "angle" [degrees]
# returns or "full" or "central" part of the rotated image
function imrotate(I,angle,spec::String="central")

  tform = recenter(RotMatrix(angle/180*pi), center(I))
  Irot = parent(warp(I,tform))

  if (spec=="full")
    Irot
  elseif (spec=="central")
    szX,szY = size(I)
    Dx = Int64(round(szX/2))
    Dy = Int64(round(szY/2))
    x0 = Int64(round(center(Irot)[1]))
    y0 = Int64(round(center(Irot)[2]))
    Ifin = Irot[x0-Dx+1:x0-Dx+szX,y0-Dy+1:y0-Dy+szY]
  else
    I
  end

end

#8

Unsure if I understand your intend, by try if the following code does what you intend. Basically I assume you would like to rotate around the center of the original image and not expand it’s size in any direction

using ImageTransformations, CoordinateTransformations, TestImages

img = testimage("camera")
tfm = recenter(RotMatrix(π/4), center(img))
imr = warp(img, tfm)
img_new  = imr[UnitRange.(indices(img))...]

#9

many thanks, this is exactly a thing I was looking for!