0

I am trying to implement some python code to separate some specific colours from an image dataset. I have separated the Cr layer from the YCbCr colour space (1-dim np array) and now I am trying to apply a curve filter similar to this in GIMP: GIMP curve I want to apply

I did some research about the topic and found that the Bezier curve is used here.I tried to explore the curves output settings, but I couldn't understand it. I want the same effect that is applied by this curve to apply thresholding in further stages. Is there an easy way that can do it? (I am a beginner to this field)

Community
  • 1
  • 1
Noussa
  • 520
  • 1
  • 4
  • 14
  • Are you asking "how do I implement curve like this in standard Python", or are you asking how you can talk to Gimp using python? – Mike 'Pomax' Kamermans Nov 09 '19 at 17:46
  • "how do I implement curve like this in standard Python" – Noussa Nov 10 '19 at 05:20
  • In that case the main important part is implementing the curve scaling itself, so in order to understand what level of beginner you're asking this question about: do you already have the scaling code written, and you're just looking for the actual function f(x)=y (taking input in [0,1] and yielding output in [0,1]) that is still missing, but you already tested it with trivial functions like `def y(x): x`, or had you not even started writing _any_ code? – Mike 'Pomax' Kamermans Nov 10 '19 at 16:03
  • I know coding in python .. I am just a beginner in image processing. Specifically, I am looking for the function that gave that curve and how to implement it in standard python or if there is any already existing function that gives that same effect with the ability to adjust some parameters to slightly change the curve. – Noussa Nov 11 '19 at 13:08
  • Note that what you're asking about is technically not image processing at all, it's just number mapping, so if you've searched so far based on the assumption this is image processing related, you probably missed out on quite a few useful other SO answers and google/duckduckgo/etc results. The function you're looking at has two simple clamp regions (e.g. f(x)=0 at some x<=a and f(x)=1 at x>=b) so that's two parameters, and the rest can honestly be any function that maps [0,1] to [0,1], so if you want that to be a Bezier you have 2 more degrees of freedom. – Mike 'Pomax' Kamermans Nov 11 '19 at 17:34
  • however, it might make more sense to use a catmull-rom curve, which is the same type of curve as a Bezier curve, with the values [rearranged a little](https://pomax.github.io/bezierinfo/#catmullconv), which has the guarantee of passing through specific points -- which seems more like what you're showing, given that there are no visible control points to manipulate. – Mike 'Pomax' Kamermans Nov 11 '19 at 17:36

1 Answers1

0

You want something like:

pdb.gimp_drawable_curves_spline(layer,HISTOGRAM_VALUE,8,[0, 0, 0.37477797513321481, 0.12890625, 0.62344582593250431, 0.8828125, 1, 1])

Trick

You can let Gimp determine the values:

Use the GUI and apply the Curves tool on a sample:

enter image description here

In the image above notice the "Presets" selector at the top. Each time you apply the filter, Gimp saves the curve, and you can retrieve it with the selector. The curve is anonymous by default (only bears a time stamp) but you can also give it a name (click the + button).

These values are saved in a file in the Gimp profile. In Gimp 2.10 this file is ${Gimp profile}/filters/GimpCurvesConfig.settings. If you edit it (your editor may need to support long lines), you will see:

# settings

(GimpCurvesConfig "2019-11-08 21:57:15"
    (time 1573246635)
    (linear no)
    (channel value)
    (curve
        (curve-type smooth)
        (points 8 0 0 0.37477797513321481 0.12890625 0.62344582593250431 0.8828125 1 1)
        (point-types 4 smooth smooth smooth smooth)

    [...snip...]

The line of interest is the one that starts with (points ...). You just need to transform:

(points 8 0 0 0.37477797513321481 0.12890625 0.62344582593250431 0.8828125 1 1)

into:

... 8,[0, 0, 0.37477797513321481, 0.12890625, 0.62344582593250431, 0.8828125, 1, 1]

Can hardly be easier.

Note:

The term "Bézier curves" is quite incidental here. It is just a way for the software to smooth the curve, but you only set anchor points. The important thing is that you define a function of a channel over itself: newChannelValue=f(oldChannelvalue) and define f() not with a mathematical formula but by drawing the graph of the function.

xenoid
  • 8,396
  • 3
  • 23
  • 49
  • Thank you so much for your reply. I just want some clarification for this line `pdb.gimp_drawable_curves_spline(layer,HISTOGRAM_VALUE,8,[0, 0, 0.37477797513321481, 0.12890625, 0.62344582593250431, 0.8828125, 1, 1])` how can I use it, or somethimg similar to it in python? – Noussa Nov 09 '19 at 05:37
  • This is the python call to the Gimp API to make the equivalent of the manual Curves editing. Of course you have to insert that in a Gimp plugin or in a Gimp batch script which I assumed you know how to do. There are equivalent solutions with other graphics libraries. See some more indication in the answer. – xenoid Nov 09 '19 at 08:52
  • Sorry, I don't know that much about GIMP plugins or this stuff. Could you give me some keywords so that I can google for? – Noussa Nov 09 '19 at 09:06
  • Google "Gimp python plugin". See [here](https://stackoverflow.com/questions/44430081/how-to-run-python-scripts-using-gimpfu-from-windows-command-line/44435560#44435560) for a batch script example. – xenoid Nov 09 '19 at 09:24
  • Thank you. So what I understood is that this is all happening inside gimp. I am actually trying to apply that curve in my jupyter notebook because I need this editing in an object detection project. Can't we use this directly in jupyter without the need of gimp? (Just getting the desired values from it). I don't know if doing what you've mentioned will lead me at the end to get the output in jupyter for further precesses. Am I right? – Noussa Nov 09 '19 at 09:46
  • Yes, since you put a "Gimp" tag... But this kind of function is fairly basic and should be in about any image library. The curve you show is also very close to the curve used to increase contrast, so a a simpler brightness/contrast function could likely do it. – xenoid Nov 09 '19 at 10:38
  • Would you recommend any Opencv or Skimage or any other famous library functions? – Noussa Nov 09 '19 at 12:14