4
\$\begingroup\$

You have two images (64x64 pixels each):

saturated picture desaturated picture

Your program must take the file names of each of them as command line arguments and determine which has more average saturation among their pixels.

The images are in ImageMagick .txt format. You can download and convert these images using convert pic.png pic.txt or download the raw text (saturated, desaturated)

Ignore the first line of the file (required).

Solutions in Assembly get 50% of their characters for free. Brainfuck, whitespace, and close variants, get 25% of their characters for free. (e.g. if it takes 200 characters in Brainfuck; mark it as 200-50=150.)

Describe your output. It could be the name of the more saturated image; the index of it (0 for first, 1 for second); true for the first, false for the second, etc. Just let us know.

It should be able to take either the saturated or desaturated image first, and accurately report the more saturated (test both ways). The filenames shouldn't be considered when evaluating saturation (e.g. no if filename contains 'desaturated'...)

Shortest answer wins. Happy coding :-)

\$\endgroup\$
7
  • 2
    \$\begingroup\$ What a hideous-looking input file format. Is it documented anywhere? \$\endgroup\$ Jan 6, 2013 at 22:25
  • \$\begingroup\$ @PeterTaylor, indeed! .txt image documentation \$\endgroup\$
    – Brigand
    Jan 6, 2013 at 22:30
  • \$\begingroup\$ @beary605, you can join the two files together if that makes it easier :-) \$\endgroup\$
    – Brigand
    Jan 6, 2013 at 23:59
  • 3
    \$\begingroup\$ How many of the 52 possible colour spaces must be supported? What bit depths must be supported? How should (partially) transparent pixels be treated for the purposes of averaging? \$\endgroup\$ Jan 7, 2013 at 13:31
  • 1
    \$\begingroup\$ How will you know that the saturation values are correctly computed? \$\endgroup\$
    – DavidC
    Jan 7, 2013 at 14:02

4 Answers 4

6
\$\begingroup\$

bash etc. and Image Magick (136 chars)

for x in "$@";do convert "$x" -colorspace HSL -channel G -separate -scale 1x1 t.txt
echo `sed "1d;s%.*#\(..\).*%\1%" t.txt` $x;done|sort

The way I see it, the easiest way to deal with the complexities of the Image Magick file format is to let Image Magick do it. t.txt seems to be the shortest possible filename which guarantees the correct output file format. The first 4 " could arguably be removed, but that would decrease robustness in the face of filenames with spaces in.

Sample output:

$ ./cmpsat.sh img-sat.txt img-desat.txt rose:
24 img-desat.txt
69 rose:
FE img-sat.txt
\$\endgroup\$
2
\$\begingroup\$

J (96 94 92)

echo/:(+/@:(m%(m=.>./)-<./)"1@:>@:(".&.>)@:((': (\(.*?\))';,1)&rxall)@:(1!:1)@:<)&.>2}.ARGV

Takes input from the command line as .txt files. It can take any number of files, and outputs a list of indices from saturated to unsaturated, i.e.:

$ jconsole saturated.j saturated.txt desaturated.txt
0 1
$ jconsole saturated.j desaturated.txt saturated.txt 
1 0

I've simplified the normal formula a bit: it does not bother to normalize the RGB values to [0..1], it uses the sum of the saturation per pixel rather than the average, and it actually calculates the inverse of the saturation and then sorts up. As long as the images are the same size (which they are), this does not affect the sort order which is what it's about.

Explanation:

  • 2}.ARGV: the command line minus its first two elements
  • &.>: for each of these, do:
  • (1!:1)@:<: read file
  • ((': (\(.*?\))';,1)&rxall): use a regex to match the pixel values
  • (".&.>): execute each match as J code. (1,2,3) becomes the list 1 2 3 so now we have the pixel values.
  • >: make a matrix from the list of lists
  • "1: operate on the rows of the matrix
  • (m%(m=.>./)-<./): MAX / (MAX - MIN), the inverse of the saturation
  • +/: sum
  • /:: sort up, so that the images are sorted in S^(-1) ascending, which gives the same order as S descending.
  • echo: output the list
\$\endgroup\$
1
  • \$\begingroup\$ Impressive! Nice explanation, too. \$\endgroup\$
    – Brigand
    Jan 6, 2013 at 21:11
1
\$\begingroup\$

Mathematica 92 215

Edit

To work directly with the Magick files I had to make substantial revisions to my first try.


Filenames

Stored as variables, x, y.

x = "http://pastebin.com/raw.php?i=5f3B4uxP";
y = "http://pastebin.com/raw.php?i=VdjDm9HK";

The following routine sorts image files by average saturation (least to greatest). (Spaces added for readability.)

i = Image; d = DigitCharacter;
f[t_] := {Mean[Flatten[ImageData[ColorConvert[i[i[Partition[(StringCases[URLFetch[t], 
   "rgb(" ~~ a : d .. ~~ "," ~~ b : d .. ~~ "," ~~c : d .. ~~ ")" :> ToExpression 
   /@ {a, b, c}])/255., 64]]], "RGB" -> "HSB"]], 1][[All, 2]]], t}

Usage

Sort@{f[x], f[y]}

Output (saturation value, followed by filename).

{{0.229977, "http://pastebin.com/raw.php?i=VdjDm9HK"},
{0.958346, "http://pastebin.com/raw.php?i=5f3B4uxP"}}


Explanation

URLFetch[x] fetches the Magick textfile, the name of which is stored in x

StringCases[URLFetch[t], "rgb(" ~~ a : d .. ~~ "," ~~ b : d .. ~~ "," ~~c : d .. ~~ ")" :> ToExpression /@ {a, b, c}])/255., 64]]], "RGB" -> "HSB"] finds the RGB values and, along with Partition converts them to the format Mathematica expects to find RGB files in.

ColorConvert converts to Hue-Saturation-Brightness values. Mean and [[All,2]] find the mean saturation values for the file.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ I think the OP is asking to get the input as a *.txt file (in ImageMagik format) and not in png format. it isn't very clear, though \$\endgroup\$ Jan 6, 2013 at 20:00
  • \$\begingroup\$ here in 79 chars f={a,b};Sort[{Mean@Mean[ImageData@ColorConvert[Import@#,"HSB"]][[;;,2]],#}&/@f] \$\endgroup\$ Jan 6, 2013 at 20:34
  • \$\begingroup\$ I was wondering about the formatting issue myself. As for your code, I'm puzzled why the double use of Mean, but I'll look more closely. \$\endgroup\$
    – DavidC
    Jan 6, 2013 at 20:56
  • \$\begingroup\$ Mean@Mean is equivalent to Mean@Flatten[...,1] but shorter \$\endgroup\$ Jan 6, 2013 at 20:58
  • 1
    \$\begingroup\$ @FakeRainBrigand This version uses the .txt files. \$\endgroup\$
    – DavidC
    Jan 10, 2013 at 15:28
0
\$\begingroup\$

Brainf**k, 117 - 25% = 87.75

Requires an interpreter with 8-bit wrapping cells (this is the most common type).

>+[,<++++[->--------<]>[>+<]++++[->++++++++<]>]>>
>+[,<++++[->--------<]>[>+<]++++[->++++++++<]>]>
[-<<<[-]>>>]<<<[.]

Just input the text render of the first image and the second image. Make sure the files end with the NUL character (ASCII value 0). If the first image is larger, it will output how much larger it is than the second one (in the ASCII value). If the second image is larger, nothing will be printed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.