# default RGB coloring

I am playing with some basic genetic algorithms to recreate input images by transparent plane figures (similar like here:). Everything would work great but the speed is terrible. I was looking for a problematic part of my code and I found that function I use - ImageDifference works very slow for CMYK colors (even if you are comparing CMYK to CMYK), but it is much faster for RGB vs RGB comparison.

The problem is that when I combine figures using Graphics like this:

Graphics[{Opacity[0.5], Red, Disk[], Green, Disk[{1, 0}]}]

the result image is in CMYK and hence, to make ImageDifference faster, I have to use ColorConvert (to RGB) which again is quite slow function.

Is there another way in Mathematica to set that all images created by Graphics will be automatically in RGB? Or if you have another ideas how to speed this up, please let me know. :)

Small demonstration:

I have some target image. For example:

target = ImageResize[ExampleData[{"TestImage", "Lena"}], 150]

In every step, I also have some combination of polygons which I want to compare to the target image. So lets say, we have (in some very early stage):

k = 5;(*number of points*)
n = 20;(*number of polygons*)

(*opacity, r, g, b, x, y*)
polygons=
Table[{RandomReal[], RandomReal[], RandomReal[], RandomReal[],
RandomReal[{0, 1}, k], RandomReal[{0, 1}, k]} // Flatten, {n}];

example1 = Graphics[
Map[
{
Opacity[#[[1]]],
RGBColor[#[[2]], #[[3]], #[[4]]],
Polygon[{Take[#, {5, 5 + k - 1}], Take[#, {5 + k, 2 k + 4}]} //Transpose]
}
&,
polygons
], ImageSize -> {150, 150}
]

For demonstration lets also set:

example2 = ColorConvert[example1, "RGB"];

Now, the difference in applying ImageData for those two representations is quite huge:

(example1 // ImageData); // AbsoluteTiming (*-> 0.0584582*)
(example2 // ImageData); // AbsoluteTiming (*-> 0.000384866*)

Same for the ImageDifference:

ImageDifference[target,example1]; // AbsoluteTiming (*-> 0.0703736*)
ImageDifference[target,example2]; // AbsoluteTiming (*-> 0.000687233*)
• "the result image is in CMYK" ...Um, it isn't? A Graphics is not an Image and doesn't have an intrinsic colour space, unless you Rasterize it or do Image[graphics, ColorSpace -> space]. How are you finding it to be "in CMYK"? – user484 Nov 21 '15 at 16:23
• Can you at least construct a minimum example to demonstrate this behavior you're seeing? – J. M.'s discontentment Nov 21 '15 at 16:26
• When you apply ImageData on a result, it will give you matrix of 4-dimensional vectors, which made me think it is in CMYK. – matt525252 Nov 22 '15 at 0:12
• Ah, you're misreading the output; it's still RGB, plus the alpha channel (which shows up due to your Opacity[] directives). Explicitly-set alpha channels slow things down in Mathematica, for some reason... – J. M.'s discontentment Nov 22 '15 at 2:44
• Ah, okay, thanks for explaining. Anyway, I still see some huge performance difference after applying ColorConvert. I updated my question and added small demonstration. – matt525252 Nov 22 '15 at 9:20

In your present example the operation that is slow is the rasterization of the Graphics expression. This is implicitly performed by both ImageDifference[target,example1] and ColorConvert[example1, "RGB"]. By pre-rasterizing for example2 you remove this costly step and the ImageDifference is two orders of magnitude faster. If you include the rasterization in the timing it is much closer, though interestingly still a bit faster.

ColorConvert[example1, "RGB"] // Head // RepeatedTiming

ImageDifference[target, example1]; // RepeatedTiming

ImageDifference[target, ColorConvert[example1, "RGB"]]; // RepeatedTiming

{0.025, Image}    (* note that the Head is Image *)

{0.030, Null}

{0.025, Null}


This question then becomes: how can one rasterize faster? Unfortunately I do not have a good answer to that. You can Rasterize directly to an Integer array, if that is your target, somewhat faster than using ImageData:

ColorConvert[example1, "RGB"] // ImageData; // RepeatedTiming

Rasterize[example1, "Data"]; // RepeatedTiming

{0.025, Null}

{0.0213, Null}


I am afraid however that this is not helpful in your situation as the integer array cannot be (directly) used as input for ImageDifference.