2

I am trying to use adapativeThreshold on a live stream that will eventually be used for shape detection. Regular threshold does not show enough of what I want to see. When I use the code below, the regular threshold comes out as expected, but the adaptive thresholds for some reason are much thinner than the original and I cannot see anything in the view. It looks like something is happening, but I can't tell what. Any ideas on how I can make the adaptive threshold windows full size?

This is what I see when I run the program in each window: enter image description here

#import packages
from documentscanner.pyimagesearch.transform import four_point_transform
from pyimagesearch.shapedetector import ShapeDetector
from skimage.filters import threshold_local
import numpy as np
import cv2
import imutils


def draw_Contours(screen, points):
    cv2.drawContours(screen, [points], -1, (0, 255, 0), 2)
    cv2.imshow("Outline", screen)


def nothing(x):
    #any operation
    pass

#access video camera
cap = cv2.VideoCapture(0)

cv2.namedWindow('Trackbars')
cv2.createTrackbar('min_edge', 'Trackbars', 75, 100, nothing)
cv2.createTrackbar('max_edge', 'Trackbars', 110,300, nothing)

while True:
    _, frame = cap.read()       #read video camera data

    minedge = cv2.getTrackbarPos('min_edge', 'Trackbars')
    maxedge = cv2.getTrackbarPos('max_edge', 'Trackbars')

    #convert image to gray scale
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (5, 5), 0)
    #blur = cv2.GaussianBlur(frame, (5, 5), 0)
    #edged = cv2.Canny(gray, minedge, maxedge)

    #threshhold instead of edging
    thresh = cv2.threshold(gray, 60, 255, cv2.THRESH_BINARY)[1]
    thresh2 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
                                    cv2.THRESH_BINARY, 11, 2)[1]
    thresh3 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,\
                                    cv2.THRESH_BINARY, 11, 2)[1]

    #find contours in edges image, keeping the largest ones, and initialize the screen contour/shapedetect
    cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    sd = ShapeDetector()
    cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]

    #loop over contours
    for c in cnts:
        #approximate the contour points
        peri = cv2.arcLength(c, True)
        approx = cv2.approxPolyDP(c, 0.02*peri, True)

        #check points in contour
        if len(approx) == 4:
            print("rectangle found: ")
            print(approx)
            draw_Contours(frame, approx)



        if len(approx) == 3:
            print("triangle found: ")
            print(approx)
            draw_Contours(frame, approx)

        if len(approx) == 2:
            print("line found: ")
            print(approx)
            draw_Contours(frame, approx)

        #show the countour(outline) of the shapes


    #show original frame and gray frame
    cv2.imshow('Frame', frame)
    #cv2.imshow('Copy', gray)
    #cv2.imshow('Edged', edged)
    cv2.imshow('Threshold', thresh)
    cv2.imshow('ThresholdGaussian', thresh2)
    cv2.imshow('ThresholdMean', thresh3)

    #detect key press and exit with escape key
    key = cv2.waitKey(1)
    if key == 27:
        break

#close the program
cap.release()
cv2.destroyAllWindows()
HansHirse
  • 18,010
  • 10
  • 38
  • 67
Samantha Garcia
  • 490
  • 6
  • 13
  • You need to post your original image and explain what you want to extract from it. Then post the simple threshold image showing what you get and want and the adaptive results. It may be that the adaptive threshold is not appropriate for your input image. – fmw42 Feb 11 '20 at 19:45
  • There is no original image. It is a live stream of the video camera. – Samantha Garcia Feb 12 '20 at 03:08

1 Answers1

2

Instead of using

thresh2 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
                                cv2.THRESH_BINARY, 11, 2)[1]
thresh3 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,\
                                cv2.THRESH_BINARY, 11, 2)[1]

Use it without numpy indexing and then this error won't occur.

thresh2 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
                                cv2.THRESH_BINARY, 11, 2) # don't use [1] 
thresh3 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,\
                                cv2.THRESH_BINARY, 11, 2)

This is because normal thresholding returns two values while adaptive thresholding returns only a single value.

Vardan Agarwal
  • 2,023
  • 2
  • 15
  • 27