'Open Cv - Emgu Cv How to find 7 segment display's rectangle area on gray scaled Image
I am creating system for reading value from 7 segment display pressure meter. For detecting digits and values from digital( Seven Segment Display) meter, i gone through following links:
- https://hackernoon.com/building-a-gas-pump-scanner-with-opencv-python-ios-116fe6c9ae8b
- https://www.pyimagesearch.com/2017/02/13/recognizing-digits-with-opencv-and-python/
- https://www.kurokesu.com/main/2017/02/20/dumb-thermometer-gets-digital-output/
- https://www.calloftechies.com/2017/12/character-recognition-explained.html
As per explanation from above links,I have created following steps for reading Digits:
- Convert Image to Gray Scale Image.
- Generating Binary images using Otsu's Algo for Threshold and Binary Inverse.
- Applying Canny Edge Detection using Otsu's threshold value.
- Find
FindContourson Canny Edge Detection.
This is working good with some images, but when dial has some light color then this is not working.
Original Image with light color.
Gray Scaled Image
Threshold Applied Image with Otsu's and Binary Inverse

You can see that there is no big color difference between Panel display section and Gauge Area so Otsu converts entire dial to whitish ignoring Panel Section
Please also see below images: original, GrayScale and Thresholded.

Please help me for figure out rectangle Thanks in Advance.
Solution 1:[1]
Here's an approach using contour approximation + contour filtering:
- Convert image to grayscale and perform Canny edge detection
- Perform morphological close
- Find contours and filter using contour approximation
- Extract ROI
Here's the detected display
Since we already have the bounding box coordinates, we extract the ROI using Numpy slicing
import cv2
image = cv2.imread('1.jpg')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(gray, 20, 200, 1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
close = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel, iterations=1)
cnts = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.01 * peri, True)
area = cv2.contourArea(approx)
if len(approx) == 4 and area > 1000:
x,y,w,h = cv2.boundingRect(approx)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 3)
ROI = original[y:y+h, x:x+w]
cv2.imshow('image', image)
cv2.imshow('ROI', ROI)
cv2.waitKey()
Solution 2:[2]
Otsu is wonderful at finding a good threshold where there are two dominants intensities. But when there are three of them (white, gray, black), it cannot guess what you want to separate.
If you apply Otsu in a window that rejects most of the background, it works fine again.
Solution 3:[3]
You may use circle detect first and then digit detect. After getting the results of digit detection, you can estimate the area with high precision. You may using yolo method as a detector.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | nathancy |
| Solution 2 | Yves Daoust |
| Solution 3 | ouflak |





