I am trying to apply a threshold to an image 1 row at a time. I want to be able to select the the row the threshold would begin and end. Ex. if I have a 1000 x 1000 image I would like to apply my threshold beginning at row 200 and end at row 850. Currently I am able to apply a threshold to an entire image.
img = cv2.imread("*.png",0)
ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
titles = ['Original Image','BINARY']
images = [img, thresh1]
for i in range(2):
plt.subplot(1,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
There are couple of ways of doing this, so I'll go from simplest and fastest, to more flexible and slower...
Simplest and fastest, if your masked area is very simple like yours:
import cv2
import numpy as np
# Load Paddington as greyscale
img = cv2.imread('paddington.png',0)
# Define a region of interest, in this case entire rows 100-300
ROI = slice(100,300)
# Threshold the region of interest, and reinsert back into image
ret,img[ROI] = cv2.threshold(img[ROI],127,255,cv2.THRESH_BINARY)
Notice I declared the ROI as a variable in just one place so that both sides of the equals sign remain correct if you change the mask's size - maintenance issue avoidance!
If your masked area was not entire rows, you could create a tuple of slices:
# Declare ROI
ROI = slice(100,300),slice(10,390)
# Threshold with mask
ret,img[ROI] = cv2.threshold(img[ROI],127,255,cv2.THRESH_BINARY)
If your masked area is more complicated, e.g. compound shapes, an outline or circular, you can still threshold only the masked region of interest! First you create a mask the same size filled with black, then draw your shapes in white and then apply the threshold to the masked region of interest:
# Make a mask the same size as the image and fill with black
mask = np.zeros_like(img)
# Draw a filled white circle onto the black mask to define a region of interest
mask = cv2.circle(mask,(200,100),100,255,-1) # -1 to fill inside circle
ROI = np.nonzero(mask)
# Threshold the region of interest, and reinsert back into image
ret, mask_thresholded = cv2.threshold(img[ROI],127,255,cv2.THRESH_BINARY)
img[ROI] = mask_thresholded.reshape(-1)
Here is the original image of the young rogue:
Keywords: Python, OpenCV, Numpy, image, image processing, mask, masked, threshold, filter, ROI, region of interest