If the problem is that the transformation function is slow to compute, a simple way to create and use a look-up table is to memoize the function:
(* create an example image *)
image = RandomImage[1, {30, 20}, ColorSpace -> "RGB"] ~ ImageResize ~ Scaled[10]
(* define the transformation function with memoization *)
mem : func[{x_, y_}] := mem = {x + 0.01 Abs@BesselJ[1, 10 x], y^2}
The first time you use the transformation, it will be slow:
AbsoluteTiming[ImageTransformation[image, func]]

But next time you use it, it will be much faster, as the values have been remembered (you could say your look-up table is stored in the DownValues
of func
)
AbsoluteTiming[ImageTransformation[image, func]]

More speed
The nice thing about ImageTransformation
is that it will interpolate between pixels so that you can sample the image at non-integer pixel positions. If you can tolerate losing the interpolation feature (i.e. so that each pixel in the output image is a direct copy of a pixel from the input image), you can get some more speed by manipulating the image data directly.
(Updated with faster code)
The code below creates a fast image transformation function for a specific size of image. Briefly, the procedure is:
- Create an
Image
expression in which the pixel values are just the integers from 1 to n (effectively labelling each pixel position with a unique identifier)
- Run the standard
ImageTranformation
on that image. The option Padding -> "Reflected"
is used to ensure that the resulting image consists only of pixels in the input image. "Periodic"
would also work.
- The result of the image transformation is flattened and rounded - this is the look-up table.
- Create a compiled function to flatten the input image data, apply the look-up table using
Part
, and partition the result.
- Sandwich the compiled function between
Image
and ImageData
The output is a function which can be applied directly to an image.
makeFastTransformation[func_, {cols_, rows_}] := Module[{lut, cfunc},
lut = ImageData @ ImageTransformation[Image @ Partition[Range[rows*cols], cols],
func, Resampling -> "Nearest", Padding -> "Reflected"];
cfunc = With[{lut = Round @ Flatten @ lut}, Compile[{{data, _Real, 3}},
Partition[Flatten[data, 1][[lut]], cols]]];
Composition[Image, cfunc, ImageData]]
The resulting function is very fast
trans = makeFastTransformation[func, ImageDimensions[image]];
AbsoluteTiming[trans @ image]

To measure the time properly we need to do the transformation several times. It came out at about about 1.4 ms on my PC, about 80 times faster than ImageTransformation
with the memoized function.
AbsoluteTiming[Do[trans @ image, {1000}]]
(* {1.3593228, Null} *)