# How can I convert colors to grayscale?

I want to change the above colored plot into a grayscale plot. I have tried this:

CCGray[pic_?ImageQ] := Module[{}, ColorConvert[pic, "GrayScale"]];


but it doesn't give me the degree of differentiation I would like.

-
@flurmer I believe your question has been answered here:mathematica.stackexchange.com/questions/8746/… –  R Hall Sep 10 '13 at 12:10
Can you operate on the BubblePlot itself? Ie. do you have access to the original data? –  David Carraher Sep 10 '13 at 12:15
@David That's an excellent question! –  Mr.Wizard Sep 10 '13 at 12:24
It is indeed what I wanna do –  flumer Sep 10 '13 at 12:32

I assume you've rejected this option:

BubbleChart[RandomReal[{-1, 1}, {10, 5, 3}],
ColorFunction -> "GrayTones"]


-
I think his response to David's question means that manipulation of an Image is indeed what he wants to do. –  Mr.Wizard Sep 10 '13 at 18:21
@Mr.Wizard lol, I misread the OPs answer comment, for a change - usually I don't understand the question! :) –  cormullion Sep 10 '13 at 18:53
Yes, I found it confusing as well, but then he Accepted my answer. Here's a pity vote: +1 :^) –  Mr.Wizard Sep 10 '13 at 21:06
@Mr.Wizard thanks, I'll treasure it! (You already had my (non-pity) vote...) –  cormullion Sep 10 '13 at 21:59
lol -- I guess you were right after all. @flumer In the future please try to make your question more clear and specific; you showed both a JPG as the input and a processing function that operates on an Image -- there is no indication that you were even generating the bubble chart yourself. –  Mr.Wizard Sep 11 '13 at 12:21

First, there is no need to use Module in your sample code above. You could write simply:

CCGray[pic_?ImageQ] := ColorConvert[pic,"GrayScale"]


Now, if you want to manage the channel mixing manually you can use ImageApply and Dot:

customGray[img_?ImageQ, ker_?VectorQ] := ImageApply[ker.# &, img]

img = Import["http://i.stack.imgur.com/wtlqF.jpg"];

customGray[img, {0.8, 0.5, -0.3}]


You'll notice that my three values add to one; this is typically necessary to preserve white as white. If you want to make this automatic just divide by the total:

customGray2[img_?ImageQ, ker_?VectorQ] := With[{k = ker/Tr@ker}, ImageApply[k.# &, img]]


Or with normalization control as an Option:

Options[customGray2] = {Normalize -> True};

customGray2[img_?ImageQ, ker_?VectorQ, OptionsPattern[]] :=
With[{k = If[OptionValue[Normalize], ker/Tr@ker, ker]},
ImageApply[k.# &, img]
]


This makes it easy to Manipulate:

Manipulate[
customGray2[img, {a, b, c}],
{a, -5, 5}, {b, -5, 5}, {c, -5, 5}
]


-
Thanks!that's REALLY what I want! –  flumer Sep 10 '13 at 12:27
@flumer You're welcome, and I'm glad I could help. However, as I tell everybody I suggest waiting 24 hours to Accept an answer, giving time for everyone around the world to reply. You never know what kind of great answer you might get if you give people a chance. (You can un-Accept by clicking the check-mark again.) –  Mr.Wizard Sep 10 '13 at 12:32
How come there are so many JPEG artifacts in your PNG images? –  Rahul Sep 10 '13 at 15:47
@Rahul This kind of extreme channel manipulation amplifies the JPEG artifacts of the original (which is not a PNG), particularly from the blue channel which receives less bytes due low human visual acuity on blue. –  Mr.Wizard Sep 10 '13 at 18:24
@Mr.Wizard It's my first question on stackexchange,i'll be careful about the answer accepted –  flumer Sep 11 '13 at 5:33

Here's an idea to post-process the grayscale image to increase the differentiation between shades. The image values (excluding pure black and white) are fed to HistogramTransformInterpolation which provides a transform function that approximately flattens the image histogram.

bc = BubbleChart[RandomReal[{-1, 1}, {10, 5, 3}]] ~ColorConvert~ "Grayscale"


ImageApply[HistogramTransformInterpolation @
DeleteCases[ImageData[bc] ~Flatten~ 1, 1. | 0.], bc]


While this seems to work okay on an uncompressed image, it is not so good with the OP's original image due to the jpeg compression:

Better results can be had by removing near-white values from the image data before computing the histogram transform, but there are still visible artefacts.

ImageApply[HistogramTransformInterpolation@
Select[ImageData[bc]~Flatten~1, 0 < # < 0.95 &], bc]


-
I wish I could try this in v7. Could you include the result of applying this to the OP's example image, for direct comparison? –  Mr.Wizard Sep 10 '13 at 14:32
@Mr.Wizard, results are, um, not that great with the original image... –  Simon Woods Sep 10 '13 at 19:57