SMALL UPDATE: This question is left as unanswered, because none of the existing answers as of yet actually use CUDA (though, whilst being very useful).
2nd Edition: To make it a bit more clear, and to summarize the discussion in comments.
I have a small image, like this one:
InsertImage =
DensityPlot[Sqrt[1 - x^2 - y^2], {x, -1, 1}, {y, -1, 1},
Frame -> False,
ColorFunction -> (Opacity[Max[Re[#], 0],
GrayLevel[Max[Re[#], 0]]] &), ImageSize -> 40,
Background -> Opacity[0, Black]]
It is just a semi-transparent gray ball:
Outside the ball you see white - because of transparency.
I have a big background, like this one:
InsertIntoImage = Image[GrayLevel[0], ImageSize -> 400];
It is just big black background.
I want to insert the small image into the big one many-many times, e.g. at these scaled positions:
PosList = {Cos[Pi #], Sin[4 Pi #]}^2 & /@ Range[0, 1, 0.005];
Vaguely, the result should be like:
Rasterize[
Graphics[{Inset[InsertIntoImage],
Inset[InsertImage, Scaled[#]] & /@ PosList},
ImageSize -> 400]] // AbsoluteTiming
Ideally:
- I want to add up only grayscale channels of big and small images.
- Small images are to be added really many times - it is for video production, and the above example is a very light version of it.
- I want to make it work fast for many more images at a time: Inset is way too slow.
Question: How to do it with CUDA?
Notes on CUDA (why CUDA):
It should work much faster. Note, the overhead of caching one small image is negligible.
I can't seem to find an appropriate inbuilt function: CUDAImageAss[] uses only images of similar size.
Putting small images pixel by pixel in matrix form is not very much to my liking. I want to be able to specify small image positions at subpixel accuracy. Normally, this would smear each pixel of each small image with a pointspread function. It is doable, but I believe there must be existing algorithms.
Such a problem must have been solved a thousand times, e.g. in videogames, movie production, etc. Note, that GPUs in videogames allow rendering in realtime, hence this approach should work fast here too.
Part
on packed arrays takes about a tenth of a second. $\endgroup$Part
be used to inset small images on top of a larger one? $\endgroup$bigarray[[100;;109, 200;;209]] += smallarray
Perhaps I have misunderstood the question? $\endgroup$InsertImage
is not actually an image but aGraphics
expression. Instead ofInset
you could useTranslate
which is quite efficient at positioning multiple copies of a single object, e.g.Graphics[Translate[InsertImage[[1]], 20 PosList], Background -> Black]
$\endgroup$