Emad Younan
Emad Younan

Reputation: 197

How to make adaptive Threshold at part on image in Opencv python?

Maybe my question is strange something but I need to make an adaptive Threshold on part of the image that the user selects with his mouse and that's my code

import cv2
img = cv2.imread("test.png")
# img2 = cv2.imread("flower.jpg")

# variables
ix = -1
iy = -1
drawing = False


def draw_reactangle_with_drag(event, x, y, flags, param):
    global ix, iy, drawing, img
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix = x
        iy = y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            img2 = cv2.imread("test.png")
            cv2.rectangle(img2, pt1=(ix, iy), pt2=(x, y),
                          color=(0, 255, 255), thickness=1)
            img = img2

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        img2 = cv2.imread("test.png")
        cv2.rectangle(img2, pt1=(ix, iy), pt2=(x, y),
                      color=(0, 255, 255), thickness=1)

        img = img2
        gray = cv2.cvtColor(img2[y: iy, x: ix], cv2.COLOR_BGR2GRAY)

        th = cv2.adaptiveThreshold(gray,
                                   255,  # maximum value assigned to pixel values exceeding the threshold
                                   cv2.ADAPTIVE_THRESH_GAUSSIAN_C,  # gaussian weighted sum of neighborhood
                                   cv2.THRESH_BINARY,  # thresholding type
                                   5,  # block size (5x5 window)
                                   3)  # constant
        img = th


cv2.namedWindow(winname="Title of Popup Window")
cv2.setMouseCallback("Title of Popup Window", draw_reactangle_with_drag)

while True:
    cv2.imshow("Title of Popup Window", img)
    if cv2.waitKey(10) == 27:
        break
cv2.destroyAllWindows()

and that's what I got at attached screenenter image description here enter image description here What am I missing?

Upvotes: 0

Views: 996

Answers (1)

fmw42
fmw42

Reputation: 53089

Here is one solution for the desired region in Python/OpenCV. It is to use division normalization rather than adaptive thresholding. (This may or may not work for other regions.)

  • Read the input
  • Specify crop coordinates for rectangle
  • Crop the image
  • Blur the cropped image
  • Divide the input by the blurred image
  • Save the result

Input:

enter image description here

import cv2
import numpy as np

# read the input
img = cv2.imread('equador.png')

# specify the crop rectangle
# 364 396 359 453   (y iy x ix)
x1 = 359
y1 = 364
x2 = 453
y2 = 396

# crop the input
crop = img[y1:y2, x1:x2]

# blur
blur = cv2.GaussianBlur(crop, (0,0), sigmaX=99, sigmaY=99)

# divide
divide = cv2.divide(crop, blur, scale=255)

# put the divide back into the input
result = img.copy()
result[y1:y2, x1:x2] = divide

# save results
cv2.imwrite('equador_crop.png', crop)
cv2.imwrite('equador_crop_blur.png', blur)
cv2.imwrite('equador_crop_divide.png', divide)
cv2.imwrite('equador_crop_divide_result.png', result)


# show results
cv2.imshow('crop', crop)
cv2.imshow('blur', blur)
cv2.imshow('divide', divide)
cv2.imshow('result', result)
cv2.waitKey(0)

Cropped Image:

enter image description here

Blurred Image:

enter image description here

Division Normalized Crop:

enter image description here

Division Normalized Replace:

enter image description here

Note: you may prefer to convert the cropped image to grayscale before blurring and then divide the grayscale version by the blurred image.

Upvotes: 1

Related Questions