Page 1 of 2

Help me to find high saturation and brightness colors.

Posted: 2017-05-17T04:30:43-07:00
by rpatelob
I have a below command and trying to achieve the same in C.

Code: Select all

convert one.jpg -scale '50x50!' -depth 8 \
'(' -clone 0 -colorspace HSB -channel gb -separate +channel -threshold 50% -compose multiply -composite ')'\
 -alpha off -compose copy_opacity -composite sparse-color:-|\
convert -size 50x50 xc: -sparse-color voronoi @- +dither -colors 6 -depth 8 -format %c histogram:info:
I couldn't understand the part of sparse-color :- and the same sparse-color in second convert command sparse-color voronoi @-

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-17T05:05:28-07:00
by snibgo
This is two "convert" commands, where the text output of the first is piped to the second.

To understand how it works, I suggest you separate the commands. Send the output of the first to a text file, and reads that text file in the second. Then you can read that text file to see what it contains.

You will see the text file has the coordinates and colours of the opaque pixels. In turn, these are pixels that have both brightness and saturation above the threshold.

The second command uses those pixel colours to colour an image. See http://www.imagemagick.org/script/comma ... arse-color

Grepping the IM library will find the C function you need for "-sparse-color voronoi @-".

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-17T06:41:53-07:00
by rpatelob
@snibgo, Thank you.
As you have suggested. I got the output from first command then saved it into text file. In the second convert I read that text file and I got the result.

Code: Select all

 convert one.jpg -scale '50x50!' -depth 8 '(' -clone 0 -colorspace HSB -channel gb -separate +channel -threshold 50% -compose multiply -composite ')' -alpha off -compose copy_opacity -composite sparse-color:-test.txt
/*Pass text file*/
convert -size 50x50 xc: -sparse-color voronoi @-test.txt +dither -colors 6 -depth 8 -format %c histogram:info:  
To achieve same result in C, MagickSparseColorImage function might be useful. In first convert sparse-color: gives a list of x, y, color. Could you tell me how do I get the colors using C, like I got from first convert?

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-17T07:13:35-07:00
by snibgo
rpatelob wrote:MagickSparseColorImage function might be useful.
Yes.

From the source code, you can see it needs an array of "double" numbers. The documentation doesn't explain this array, but you can see it calls SparseColorImage(), which is in distort.c, which explains:
% o arguments: array of floating point arguments for this method--
% x,y,color_values-- with color_values given as normalized values.
So you need to set up this array with coordinates and colours of opaque pixels from the image you have created. The obvious way to do this is in a y,x loop that reads the image and, for each opaque pixel, populate the next few array elements.

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-17T07:35:24-07:00
by rpatelob
% o arguments: array of floating point arguments for this method--
% x,y,color_values-- with color_values given as normalized values.
Yes, you are right but how do I get those values "x,y, color_values" in C? In CLI, the first convert command gives me those values.
And the second convert command uses those values and return 6 colors.

Code: Select all

convert -size 50x50 xc: -sparse-color voronoi @-test.txt +dither -colors 6 -depth 8 -format %c histogram:info:  

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-17T07:55:17-07:00
by snibgo
As I said: The obvious way to do this is in a y,x loop that reads the image and, for each opaque pixel, populate the next few array elements.

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-19T07:14:29-07:00
by rpatelob
Thank you @snibgo
I have done it. :D

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-19T08:48:03-07:00
by el_supremo
@rpatelob
Would you mind showing your code? I've almost got that working except for the last step.

Pete

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-22T07:49:58-07:00
by rpatelob
Yes sure!
Here is the code. I have skipped all other operations. Please check my below code, you will get the Sparse Colors.

Code: Select all

		size_t height = MagickGetImageHeight(wand);
		size_t width = MagickGetImageWidth(wand);
		size_t spares_index = 0;
		// Allocated enough memory to hold Sparse Color data
		double * sparse_args = malloc(sizeof(double) * height * width * 5);
		// Iterate over pixel data
		iteration = NewPixelIterator(wand);
		for (y = 0; y < height; ++ y)
		{
		    row = PixelGetNextIteratorRow(iteration, &row_width);
		    for (x = 0; x < row_width; ++x)
		    {
		        PixelGetMagickColor(row[x], &pixel);
		        // Append coord + color data if pixel is visible.
		        if (pixel.alpha == QuantumRange) {
		            sparse_args[spares_index++] = (double)x;
		            sparse_args[spares_index++] = (double)y;
		            sparse_args[spares_index++] = pixel.red / QuantumRange;
		            sparse_args[spares_index++] = pixel.green/ QuantumRange;
		            sparse_args[spares_index++] = pixel.blue / QuantumRange;
						}
		    }
		}
		iteration = DestroyPixelIterator(iteration);
		wand = DestroyMagickWand(wand);
This is first part. And as I said I skipped other operations like composite, scale, etc.
Now you just need to pass sparse_args to second part. Below is the second part.

Code: Select all

		MagickWand * final;
		final = NewMagickWand();
		MagickSetSize(final, 50, 50);
		MagickReadImage(final, "xc:");
		MagickSparseColorImage(final, VoronoiColorInterpolate, spares_index, sparse_args);
		MagickQuantizeImage(final, 6, UndefinedColorspace, 0, NoDitherMethod, MagickFalse);
Now find Histogram info for this wand, using MagickGetImageHistogram method.

Let me know if you still have some doubts.

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-22T09:28:54-07:00
by el_supremo
Thanks.
I was dividing the pixel colours by 256 instead of QuantumRange. I'm using a Q16 IM so 256 doesn't work too well.
Now to figure out why I get 6 colours but they aren't the right ones.

Pete

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-24T09:42:41-07:00
by el_supremo
Could you post the code which does the first convert command? I'm using the logo: image as input and my code produces two extra colours in the output, all the other are identical to the output from the convert command.

Pete

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-25T07:36:30-07:00
by rpatelob
Check below code, you will get the sparse colours from it. This is the first part, double sparse_args hold all sparse colours, now you just need to pass sparse_args to second part. Check my previous post for second part. Let me know if you still not get the expected output.

Code: Select all

                MagickWand * wand, * wand0, * wand1;
		PixelIterator * iteration;
		PixelWand ** row;
		PixelInfo pixel;
		size_t x, y, row_width;

		wand = NewMagickWand();
		MagickReadImage(wand, "one.jpg");
		MagickSetImageAlphaChannel(wand, OffAlphaChannel);

		MagickScaleImage(wand, 50, 50);
		MagickSetImageDepth(wand,8);

		wand0 = CloneMagickWand(wand);
		wand1 = CloneMagickWand(wand);

		MagickTransformImageColorspace(wand0, HSBColorspace);
		MagickSetImageChannelMask(wand0, GreenChannel);
		MagickSeparateImage(wand0, GreenChannel);
		MagickThresholdImage(wand0, QuantumRange*50/100);

		MagickTransformImageColorspace(wand1, HSBColorspace);
		MagickSetImageChannelMask(wand1, BlueChannel);
		MagickSeparateImage(wand1, BlueChannel);
		MagickThresholdImage(wand1, QuantumRange*50/100);

		MagickCompositeImage(wand0, wand1, MultiplyCompositeOp, MagickFalse, 0, 0);

		wand1 = DestroyMagickWand(wand1);

		MagickSetImageAlphaChannel(wand, OffAlphaChannel);
		MagickCompositeImage(wand, wand0, CopyAlphaCompositeOp, MagickFalse, 0, 0);

		wand0 = DestroyMagickWand(wand0);

		size_t height = MagickGetImageHeight(wand);
		size_t width = MagickGetImageWidth(wand);
		size_t spares_index = 0;
		// Allocated enough memory to hold Sparse Color data
		double * sparse_args = malloc(sizeof(double) * height * width * 5);
		// Iterate over pixel data
		iteration = NewPixelIterator(wand);
		for (y = 0; y < height; ++ y)
		{
		    row = PixelGetNextIteratorRow(iteration, &row_width);
		    for (x = 0; x < row_width; ++x)
		    {
		        PixelGetMagickColor(row[x], &pixel);
		        // Append coord + color data if pixel is visible.
		        if (pixel.alpha == QuantumRange) {
		            sparse_args[spares_index++] = (double)x;
		            sparse_args[spares_index++] = (double)y;
		            sparse_args[spares_index++] = pixel.red / QuantumRange;
		            sparse_args[spares_index++] = pixel.green/ QuantumRange;
		            sparse_args[spares_index++] = pixel.blue / QuantumRange;
						}
		    }
		}
		iteration = DestroyPixelIterator(iteration);
		wand = DestroyMagickWand(wand);

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-30T08:14:36-07:00
by el_supremo
Thanks for posting your code.
It produces the same output for the logo: image as my code does and they don't agree with the command line output.
This command line:

Code: Select all

convert one.jpg -scale '50x50!' -depth 8 \
'(' -clone 0 -colorspace HSB -channel gb -separate +channel -threshold 50% -compose multiply -composite ')'\
 -alpha off -compose copy_opacity -composite sparse-color:
produces 125 pixels:

Code: Select all

17,4,srgba(255,121,121,1)
17,5,srgba(255,66,66,1)
20,5,srgba(255,70,70,1)
21,5,srgba(255,115,115,1)
22,5,srgba(255,98,98,1)
15,6,srgba(255,109,109,1)
18,6,srgba(255,97,97,1)
19,6,srgba(255,85,85,1)
20,6,srgba(255,84,84,1)
21,6,srgba(255,96,96,1)
22,6,srgba(255,112,112,1)
23,6,srgba(255,125,125,1)
24,6,srgba(255,122,122,1)
25,6,srgba(255,122,122,1)
15,7,srgba(255,118,118,1)
22,7,srgba(255,85,85,1)
24,7,srgba(255,126,126,1)
26,7,srgba(255,57,57,1)
14,8,srgba(255,112,112,1)
26,8,srgba(255,99,99,1)
13,9,srgba(255,94,94,1)
14,9,srgba(255,92,92,1)
12,10,srgba(255,93,93,1)
36,10,srgba(49,75,139,1)
12,11,srgba(255,95,95,1)
35,11,srgba(189,191,78,1)
34,12,srgba(36,64,145,1)
35,12,srgba(229,225,61,1)
10,13,srgba(255,120,120,1)
11,13,srgba(255,111,111,1)
21,13,srgba(149,147,74,1)
34,13,srgba(61,84,134,1)
10,14,srgba(255,113,113,1)
9,15,srgba(255,118,118,1)
10,15,srgba(255,91,91,1)
33,15,srgba(34,62,146,1)
34,15,srgba(40,67,143,1)
33,16,srgba(38,65,144,1)
33,17,srgba(227,223,62,1)
21,20,srgba(160,101,68,1)
22,20,srgba(141,89,62,1)
23,20,srgba(168,112,83,1)
30,20,srgba(205,125,85,1)
31,20,srgba(207,128,88,1)
22,21,srgba(208,121,77,1)
23,21,srgba(202,125,86,1)
33,21,srgba(187,115,78,1)
22,22,srgba(140,79,48,1)
23,22,srgba(241,143,94,1)
33,22,srgba(202,126,88,1)
23,23,srgba(137,73,42,1)
24,23,srgba(153,97,75,1)
25,23,srgba(64,81,130,1)
30,23,srgba(165,103,72,1)
33,23,srgba(240,142,93,1)
34,23,srgba(182,117,85,1)
25,24,srgba(32,58,137,1)
33,24,srgba(229,135,88,1)
25,25,srgba(34,62,146,1)
33,25,srgba(197,111,69,1)
25,26,srgba(34,60,142,1)
26,26,srgba(34,61,144,1)
25,27,srgba(35,55,133,1)
26,27,srgba(34,62,146,1)
27,27,srgba(34,62,145,1)
26,28,srgba(35,61,144,1)
27,28,srgba(34,62,146,1)
27,29,srgba(35,60,142,1)
28,32,srgba(34,60,142,1)
28,33,srgba(34,60,143,1)
37,33,srgba(33,59,139,1)
38,33,srgba(34,59,139,1)
38,34,srgba(35,54,130,1)
29,35,srgba(32,59,138,1)
29,36,srgba(34,62,146,1)
29,37,srgba(34,62,146,1)
30,37,srgba(31,57,133,1)
29,38,srgba(34,62,146,1)
30,38,srgba(34,62,146,1)
29,39,srgba(34,62,146,1)
30,39,srgba(34,62,146,1)
31,39,srgba(34,62,145,1)
29,40,srgba(34,62,146,1)
30,40,srgba(34,62,146,1)
31,40,srgba(34,62,146,1)
32,40,srgba(33,61,143,1)
29,41,srgba(31,56,131,1)
30,41,srgba(34,62,146,1)
31,41,srgba(34,62,146,1)
32,41,srgba(34,62,146,1)
33,41,srgba(34,62,146,1)
30,42,srgba(34,62,146,1)
31,42,srgba(34,62,146,1)
32,42,srgba(34,62,146,1)
33,42,srgba(34,62,146,1)
34,42,srgba(34,62,146,1)
35,42,srgba(34,62,146,1)
36,42,srgba(34,62,146,1)
37,42,srgba(35,60,142,1)
30,43,srgba(34,62,145,1)
31,43,srgba(34,62,146,1)
32,43,srgba(34,62,146,1)
33,43,srgba(34,62,146,1)
34,43,srgba(34,62,146,1)
35,43,srgba(34,62,146,1)
36,43,srgba(34,62,146,1)
37,43,srgba(35,61,143,1)
31,44,srgba(34,62,146,1)
32,44,srgba(34,62,146,1)
33,44,srgba(34,62,146,1)
34,44,srgba(34,62,146,1)
35,44,srgba(34,62,146,1)
36,44,srgba(34,62,146,1)
37,44,srgba(35,60,142,1)
30,45,srgba(161,35,38,1)
32,45,srgba(31,56,131,1)
33,45,srgba(34,62,146,1)
34,45,srgba(34,62,146,1)
35,45,srgba(34,62,146,1)
36,45,srgba(34,62,145,1)
37,45,srgba(38,54,131,1)
30,46,srgba(161,24,27,1)
31,46,srgba(134,20,23,1)
35,46,srgba(34,54,130,1)
40,46,srgba(162,27,33,1)
But the code posted by @rpatelob in the previous message (and my code) produces these 127 pixels:

Code: Select all

23,2,srgba(142,141,71,1)
17,4,srgba(255,121,121,1)
17,5,srgba(255,66,66,1)
20,5,srgba(255,70,70,1)
21,5,srgba(255,115,115,1)
22,5,srgba(255,98,98,1)
15,6,srgba(255,109,109,1)
18,6,srgba(255,97,97,1)
19,6,srgba(255,85,85,1)
20,6,srgba(255,84,84,1)
21,6,srgba(255,96,96,1)
22,6,srgba(255,112,112,1)
23,6,srgba(255,125,125,1)
24,6,srgba(255,122,122,1)
25,6,srgba(255,122,122,1)
15,7,srgba(255,118,118,1)
22,7,srgba(255,85,85,1)
24,7,srgba(255,126,126,1)
26,7,srgba(255,57,57,1)
14,8,srgba(255,112,112,1)
26,8,srgba(255,99,99,1)
13,9,srgba(255,94,94,1)
14,9,srgba(255,92,92,1)
12,10,srgba(255,93,93,1)
36,10,srgba(49,75,139,1)
12,11,srgba(255,95,95,1)
35,11,srgba(189,191,78,1)
34,12,srgba(36,64,145,1)
35,12,srgba(229,225,61,1)
36,12,srgba(165,168,84,1)
10,13,srgba(255,120,120,1)
11,13,srgba(255,111,111,1)
21,13,srgba(149,147,74,1)
34,13,srgba(61,84,134,1)
10,14,srgba(255,113,113,1)
9,15,srgba(255,118,118,1)
10,15,srgba(255,91,91,1)
33,15,srgba(34,62,146,1)
34,15,srgba(40,67,143,1)
33,16,srgba(38,65,144,1)
33,17,srgba(227,223,62,1)
21,20,srgba(160,101,68,1)
22,20,srgba(141,89,62,1)
23,20,srgba(168,112,83,1)
30,20,srgba(205,125,85,1)
31,20,srgba(207,128,88,1)
22,21,srgba(208,121,77,1)
23,21,srgba(202,125,86,1)
33,21,srgba(187,115,78,1)
22,22,srgba(140,79,48,1)
23,22,srgba(241,143,94,1)
33,22,srgba(202,126,88,1)
23,23,srgba(137,73,42,1)
24,23,srgba(153,97,75,1)
25,23,srgba(64,81,130,1)
30,23,srgba(165,103,72,1)
33,23,srgba(240,142,93,1)
34,23,srgba(182,117,85,1)
25,24,srgba(32,58,137,1)
33,24,srgba(229,135,88,1)
25,25,srgba(34,62,146,1)
33,25,srgba(197,111,69,1)
25,26,srgba(34,60,142,1)
26,26,srgba(34,61,144,1)
25,27,srgba(35,55,133,1)
26,27,srgba(34,62,146,1)
27,27,srgba(34,62,145,1)
26,28,srgba(35,61,144,1)
27,28,srgba(34,62,146,1)
27,29,srgba(35,60,142,1)
28,32,srgba(34,60,142,1)
28,33,srgba(34,60,143,1)
37,33,srgba(33,59,139,1)
38,33,srgba(34,59,139,1)
38,34,srgba(35,54,130,1)
29,35,srgba(32,59,138,1)
29,36,srgba(34,62,146,1)
29,37,srgba(34,62,146,1)
30,37,srgba(31,57,133,1)
29,38,srgba(34,62,146,1)
30,38,srgba(34,62,146,1)
29,39,srgba(34,62,146,1)
30,39,srgba(34,62,146,1)
31,39,srgba(34,62,145,1)
29,40,srgba(34,62,146,1)
30,40,srgba(34,62,146,1)
31,40,srgba(34,62,146,1)
32,40,srgba(33,61,143,1)
29,41,srgba(31,56,131,1)
30,41,srgba(34,62,146,1)
31,41,srgba(34,62,146,1)
32,41,srgba(34,62,146,1)
33,41,srgba(34,62,146,1)
30,42,srgba(34,62,146,1)
31,42,srgba(34,62,146,1)
32,42,srgba(34,62,146,1)
33,42,srgba(34,62,146,1)
34,42,srgba(34,62,146,1)
35,42,srgba(34,62,146,1)
36,42,srgba(34,62,146,1)
37,42,srgba(35,60,142,1)
30,43,srgba(34,62,145,1)
31,43,srgba(34,62,146,1)
32,43,srgba(34,62,146,1)
33,43,srgba(34,62,146,1)
34,43,srgba(34,62,146,1)
35,43,srgba(34,62,146,1)
36,43,srgba(34,62,146,1)
37,43,srgba(35,61,143,1)
31,44,srgba(34,62,146,1)
32,44,srgba(34,62,146,1)
33,44,srgba(34,62,146,1)
34,44,srgba(34,62,146,1)
35,44,srgba(34,62,146,1)
36,44,srgba(34,62,146,1)
37,44,srgba(35,60,142,1)
30,45,srgba(161,35,38,1)
32,45,srgba(31,56,131,1)
33,45,srgba(34,62,146,1)
34,45,srgba(34,62,146,1)
35,45,srgba(34,62,146,1)
36,45,srgba(34,62,145,1)
37,45,srgba(38,54,131,1)
30,46,srgba(161,24,27,1)
31,46,srgba(134,20,23,1)
35,46,srgba(34,54,130,1)
40,46,srgba(162,27,33,1)
The first and 30th entries in the second list are not in the first one.

Anyone got any ideas why they are different?

Pete

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-30T09:33:23-07:00
by snibgo
The CLI given by el_supremo looks the same as the C code from rpatelob, but with a possible problem in "QuantumRange*50/100" which might cause integer overflow or rounding problems. I would express this by "QuantumRange*(50.0/100.0)".

I assume, of course, that identical versions of IM are used for both.

As the two outputs don't match, I suggest both versions are given "write" commands for each intermediate image. This should isolate where the difference occurs.

Re: Help me to find high saturation and brightness colors.

Posted: 2017-05-30T09:51:56-07:00
by el_supremo
Hi snibgo:
I just tried "QuantumRange*50./100" and "QuantumRange*0.5" and they don't change the output.
I'm using ImageMagick 7.0.5-5 Q16 x64
I did output intermediate images but I only eyeballed them. I'll let IM compare them to see if there are any differences.

Thanks
Pete