1
$\begingroup$

How do I find the first derivative of a coordinate set using Python?

I have a list of (x,y) coordinates (plotted below in red) representing a dotted-line perpendicular between two points (connected in blue).

gray For each red point along the dotted-line, I can get the grayscale value of the pixel over which the dot runs, and write all 3 variables to a csv file like so:

pixel coordinates and grayscale...

I know it has to do with finding the rate of change in grayscale, but I'm very new to image processing and coding grown-up math. Rabbitholing brought me to Sobel & Convolution Equations, but these seem like Final Boss-level implementations and I wanted to ask the community for input and direction to lower hanging fruit before jumping into the fire.

$\endgroup$
2
  • $\begingroup$ Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. $\endgroup$
    – Community Bot
    Jun 14, 2022 at 15:48
  • $\begingroup$ It is something of a dictum here that asking for coding help should be accompanied by a sketch of the scientific (or perhaps "technical") computation that motivates the request. If you haven't done so already, I can recommend taking the site tour and perusing the Help FAQ to get an overview. $\endgroup$
    – hardmath
    Aug 16, 2022 at 17:23

1 Answer 1

2
$\begingroup$

A gradient is not immediately well defined for digital images because they are both:

  1. Quantized (the image values have a finite number of possible values E.g. 0-255 or likewise)
  2. The image is discretized. That is, the pixels are located at whole number coordinate points, E.g. (3, 5) or (1, 12).

This means that any approach to calculate the derivative of the image, in some way, will be an approximate method. There are a number of approaches.

Of common approaches I can think of from the top of my head are:

  1. Using a finite difference method. That is, for a first-order approach, instead of calculating $\frac{f(x+h)-f(x)}{h}$ in the $\lim\limits_{h\to0}$, you let $h$ be some positive value. This still leaves an issue of how to handle the discrete nature of the pixels. Therefore choosing $h$ to be 1, means you are calculating the difference between pixels.
  2. Alternatively, you first fit a smooth function to your image, a 2d polynomial or similar, of which you can find the derivative and then let this derivative be the substitute for the image. This will be more complicated than calculating the sobel filter.

What you have done, it seems, is to interpolate the grayscale values between the discrete image pixels using a nearest neighbor interpolation. I can deduce that you didn't show the whole list of values because the grayscale values here only have slight variations. You could go by the interpolated coordinates, and calculate a finite difference directly on those. However, your step size is too small using the nearest neighbor interpolation, and you will thus end with the derivative being 0 (mostly) and occasionally 1, I predict. If you increase the step size this should work.

Alternatively, you interpolate using a more refined approach, you can look into bilinear interpolation. Letting two consecutive points on the line be denoted by p[i] and p[i+1], with I[p[i]], I[p[i+1]] be the grayscale values and |p[i+1]-p[i]| denote the distance. You can estimate the derivative at p[i] by (I[p[i+1]]-I[p[i]])/|p[i+1]-p[i]|. What you get is the slope of the image at p[i] of the image along that red line.

Alternatively, you abandon the interpolated line and calculate the derivative directly in the image using finite difference. Doing something like:

import numpy as np
from PIL import Image
image = np.array(Image.open('your_image.png'))
di = image[:-1,1:] - image[1:,1:]
dj = image[1:,:-1] - image[1:,1:]
mag = np.sqrt(di**2 + dj**2)

should work. Here di is the derivative along columns and dj is the derivative along the rows. mag holds the gradient magnitude.

A mention on convolutions. They don't particularly help you calculate filters on images unless you are interested in some specific properties of the Fourier space or need the filter application to be fast (using FFT fast Fourier transforms). It's a nice theoretic framework but not one that improves the results in this case. Usually rather the opposite.

$\endgroup$
2
  • 2
    $\begingroup$ It is also possible to interpolate the image in 2D (pixel value as a function of both coordinates) with a spline via Scipy. Then the spline can de birectly derived to obtain the gradient of the image, using the spline-specific routines of Scipy. Otherwise you can compute the gradient very simply by applying finite differences directly on the interpolation. $\endgroup$
    – Laurent90
    Aug 16, 2022 at 14:59
  • $\begingroup$ Thank you both for these suggestions, will take the time and work through each. Very much appreciated. $\endgroup$
    – Kelly
    Aug 24, 2022 at 0:13

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.