Measuring the width of a hot steel plate with OpenCV

Question:

I want to measure the width along the green line in the image, I applied filters like canny via OpenCV but I guess the filter didn’t work (can’t show the edges) because of the very high temperature. My idea is to draw 2 vertical lines and measure by drawing a line between them (I want to draw the vertical edges of the object in the picture, so). Is there any method that can work for this?

Steel Plate

Asked By: Tony Stark

||

Answers:

  • take a row of pixels
  • take red channel only (others contain no information)
  • lowpass it a bit to suppress noise
  • gradient
  • maximum and minimum are rising and falling edge

From that, falling - rising, you directly have the width in pixels of your workpiece, at that scanline through the image.

You could also, and maybe should, use a global threshold instead of going for edges. In this picture, a threshold of 0.4 looks good. You could use Otsu’s method to determine that.

im = cv.imread("UEj1P.png")

# try threshold using Otsu
row_u8 = im[550, :, 2] # red channel
(otsulevel, thresh) = cv.threshold(row_u8, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)

row = im[500:550, :, 2].mean(axis=0) / 255

lowpassed = scipy.ndimage.gaussian_filter1d(row, sigma=2.0)

gradient = np.gradient(lowpassed)

rising = np.argmax(gradient)
falling = np.argmin(gradient)

# two plots in the figure
fig, ax = plt.subplots(2, 1, figsize=(15, 10))

# first plot: row
ax[0].plot(row)
ax[0].plot(lowpassed)

# otsu threshold line
ax[0].axhline(otsulevel/255, color="blue")

# second plot: gradient
ax[1].plot(gradient)

# draw some vertical lines at rising and falling edge
ax[0].axvline(x=rising, color="red")
ax[0].axvline(x=falling, color="red")
ax[1].axvline(x=rising, color="red")
ax[1].axvline(x=falling, color="red")

plt.show()

plots

Answered By: Christoph Rackwitz

The red component binarizes wonderfully, so it won’t be a big deal to find the sides.

For more accuracy, you can lowpass filter vertically to reduce noise. You can also do subpixel interpolation by using a linear model that straddles the edge. But I am not sure that this luxury is required for your case.

enter image description here

Lowpassed:

enter image description here

Answered By: user1196549