14

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.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
flumer
  • 143
  • 1
  • 5

3 Answers3

17

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["https://i.stack.imgur.com/wtlqF.jpg"];

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

enter image description here

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}
]

enter image description here

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Thanks!that's REALLY what I want! – flumer Sep 10 '13 at 12:27
  • 2
    @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? –  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
7

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"

enter image description here

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

enter image description here

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:

enter image description here

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]

enter image description here

Simon Woods
  • 84,945
  • 8
  • 175
  • 324
7

I assume you've rejected this option:

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

gray bubbles

cormullion
  • 24,243
  • 4
  • 64
  • 133
  • 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
  • 1
    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
  • I realize it is a more concise answer! – flumer Sep 11 '13 at 05:37
  • @Mr.Wizard your vote repaid dividends, it seems‽ :) – cormullion Sep 11 '13 at 06:18
  • 1
    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
  • i just wanna to grayrize a picture no matter what sorts of,so i just take a representative picture.i'll mention it next time – flumer Sep 20 '13 at 16:59