Ask Your Question

Revision history [back]

Detect decimal/small dot in image

I'm following Adrian Rosebrock's tutorial on recognising digits: https://www.pyimagesearch.com/2017/02/13/recognizing-digits-with-opencv-and-python/

But it doesn't recognise decimal points, so I've been trying really hard to create a part that would help to do that. I think I've gotten close, but I'm not sure what I've done wrong.

This is my image after preprocessing

Original

and this is what happens after the processing

image description

As you can see, I'm doing something wrong somewhere

More examples:

image description

image description

Can anyone guide me on what I should do? I'm really lost here

================================================================

The images i'm using image description

image description

The code I'm using

from imutils.perspective import four_point_transform
from imutils import contours
import imutils
import cv2
import numpy

DIGITS_LOOKUP = {
        # Old Library
    #(1, 1, 1, 0, 1, 1, 1): 0, # same as new 8
    (0, 0, 1, 0, 0, 1, 0): 1,
    (1, 0, 1, 1, 1, 1, 0): 2,
    (1, 0, 1, 1, 0, 1, 1): 3,
    (0, 1, 1, 1, 0, 1, 0): 4,
    (1, 1, 0, 1, 0, 1, 1): 5,
    #(1, 1, 0, 1, 1, 1, 1): 6,
    (1, 0, 1, 0, 0, 1, 0): 7,
    (1, 1, 1, 1, 1, 1, 1): 8,
    (1, 1, 1, 1, 0, 1, 1): 9,

    # New Digital Library
        (0, 0, 1, 1, 1, 0, 1): 0,
        (1, 0, 1, 0, 0, 1, 1): 2,

        (0, 0, 1, 1, 0, 1, 1): 4,
        (0, 0, 0, 0, 0, 1, 1): 4,

        (1, 1, 0, 0, 0, 1, 1): 5,
        (1, 1, 0, 1, 1, 0, 1): 5,
        (1, 0, 0, 0, 0, 1, 1): 5,

        (1, 1, 1, 0, 0, 0, 0): 7,

        (1, 1, 0, 1, 1, 1, 1): 8,
        (1, 1, 1, 0, 1, 1, 1): 8
}

image = cv2.imread("10.jpg")

image = imutils.resize(image, height=100)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 120, 255, 1)
cv2.imshow("1", edged)

cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
displayCnt = None

for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)

    if len(approx) == 4:
        displayCnt = approx
        break

warped = four_point_transform(gray, displayCnt.reshape(4, 2))
output = four_point_transform(image, displayCnt.reshape(4, 2))

thresh = cv2.threshold(warped, 0, 255,
    cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imshow("2", thresh)
print(thresh.shape)

circles = cv2.HoughCircles(warped, cv2.HOUGH_GRADIENT, 7, 14, param1=0.1, param2=20, minRadius=3, maxRadius=7)

# ensure at least some circles were found
if circles is not None:
    circles = numpy.round(circles[0, :]).astype("int")

    for (x, y, r) in circles:
        cv2.circle(output, (x, y), r, (0, 255, 0), 4)
        cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)


    # show the output image
    cv2.imshow("test", output)
    cv2.waitKey(0)

Detect decimal/small dot in image

I'm following Adrian Rosebrock's tutorial on recognising digits: https://www.pyimagesearch.com/2017/02/13/recognizing-digits-with-opencv-and-python/

But it doesn't recognise decimal points, so I've been trying really hard to create a part that would help to do that. I think I've gotten close, but I'm not sure what I've done wrong.

This is my image after preprocessing

Original

and this is what happens after the processing

image description

As you can see, I'm doing something wrong somewhere

More examples:

image description

image description

Can anyone guide me on what I should do? I'm really lost here

================================================================

The images i'm using image description

image description

The code I'm using

from imutils.perspective import four_point_transform
from imutils import contours
import imutils
import cv2
import numpy

DIGITS_LOOKUP = {
        # Old Library
    #(1, 1, 1, 0, 1, 1, 1): 0, # same as new 8
    (0, 0, 1, 0, 0, 1, 0): 1,
    (1, 0, 1, 1, 1, 1, 0): 2,
    (1, 0, 1, 1, 0, 1, 1): 3,
    (0, 1, 1, 1, 0, 1, 0): 4,
    (1, 1, 0, 1, 0, 1, 1): 5,
    #(1, 1, 0, 1, 1, 1, 1): 6,
    (1, 0, 1, 0, 0, 1, 0): 7,
    (1, 1, 1, 1, 1, 1, 1): 8,
    (1, 1, 1, 1, 0, 1, 1): 9,

    # New Digital Library
        (0, 0, 1, 1, 1, 0, 1): 0,
        (1, 0, 1, 0, 0, 1, 1): 2,

        (0, 0, 1, 1, 0, 1, 1): 4,
        (0, 0, 0, 0, 0, 1, 1): 4,

        (1, 1, 0, 0, 0, 1, 1): 5,
        (1, 1, 0, 1, 1, 0, 1): 5,
        (1, 0, 0, 0, 0, 1, 1): 5,

        (1, 1, 1, 0, 0, 0, 0): 7,

        (1, 1, 0, 1, 1, 1, 1): 8,
        (1, 1, 1, 0, 1, 1, 1): 8
}

image = cv2.imread("10.jpg")

image = imutils.resize(image, height=100)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 120, 255, 1)
cv2.imshow("1", edged)

cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
displayCnt = None

for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)

    if len(approx) == 4:
        displayCnt = approx
        break

warped = four_point_transform(gray, displayCnt.reshape(4, 2))
output = four_point_transform(image, displayCnt.reshape(4, 2))

thresh = cv2.threshold(warped, 0, 255,
    cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imshow("2", thresh)
print(thresh.shape)

circles = cv2.HoughCircles(warped, cv2.HOUGH_GRADIENT, 7, 14, param1=0.1, param2=20, minRadius=3, maxRadius=7)

# ensure at least some circles were found
if circles is not None:
    circles = numpy.round(circles[0, :]).astype("int")

    for (x, y, r) in circles:
        cv2.circle(output, (x, y), r, (0, 255, 0), 4)
        cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)


    # show the output image
    cv2.imshow("test", output)
    cv2.waitKey(0)