I have an issue which I can't work around since I'm not very fluent with python and opencv.
Suppose I have an image, I convert to grayscale, I threshold it, perform some dilate and erode and finally I am able to retrieve a list of contours. Some code:
imfile = path + f
origimage = cv.imread(imfile)
#from RGB to grayscale
imgray = cv.imread(imfile, cv.IMREAD_GRAYSCALE)
#thresholding
ret,thresholded = cv.threshold(imgray,chosenThresh,255,cv.THRESH_BINARY)
dKernel = np.ones((12,12),np.uint8)
opened = cv.morphologyEx(thresholded, cv.MORPH_CLOSE, dKernel)
#the kernel
sharpkrnl = np.array([[0,-1,0], [-1,5,-1], [0,-1,0]])
sharpened = cv.filter2D(opened, -1, sharpkrnl)
sharpened = cv.bitwise_not(sharpened)
#find contours
h, w = sharpened.shape[:2]
_, contours0, hierarchy = cv.findContours(sharpened.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
contours = [cv.approxPolyDP(cnt, 3, True) for cnt in contours0]
now the question is...I run through the found contours and, if some of these does not fit my requirements, in particular if it is too big, I want to get a ROI of the image that is exactly what's inside the contour in order to perform a thresholding and all the above only to this region, in order to see if I can do a better contouring of the cropped image.
This question partially address my issue: How to crop the internal area of a contour?
EDIT
the Masking out the infomation allows me extracting the ROI but I also need the exact image with the same colours of the original in order to perform thresholding and all the other operations. The code provided in the answer I mentioned requires a grayscale image. This the original code:
import numpy as np
import cv2
img = cv2.imread('...', 0) # Read in your image
contours, _ = cv2.findContours(...) # Your call to find the contours
idx = ... # The index of the contour that surrounds your object
mask = np.zeros_like(img) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask, contours, idx, 255, -1) # Draw filled contour in mask
out = np.zeros_like(img) # Extract out the object and place into output image
out[mask == 255] = img[mask == 255]
I, on the other side, have an imgray as from the code above. Is it the same as in the example I found? What should I do, instead, in order to get a ROI that contains the imgray so that I can perform the same operations as shown above? Ideas?
EDIT II
this code
mask = np.zeros_like(imgray) # Create mask where white is what we want, black otherwise
cv.drawContours(mask, [c], -1, 255, -1) # Draw filled contour in mask
out = np.zeros_like(imgray) # Extract out the object and place into output image
out[mask == 255] = imgray[mask == 255]
seems to, at least, return a grayscale image. But it's showing the whole image and not the countour I am expecting...ideas?
ok, I believe I found the answer I was looking for. What I am doing is the following:
#by doing so I am getting a ROI over the imgray image
#which can be used to, later, perform analysis
mask = np.zeros_like(imgray) # Create mask where white is what we want, black otherwise
cv.drawContours(mask, [c], -1, 255, -1) # Draw filled contour in mask
out = np.zeros_like(imgray) # Extract out the object and place into output image
out[mask == 255] = imgray[mask == 255]
#then simply proceed with the analysis:
chosenThresh = 120
ret,thresholded = cv.threshold(out,chosenThresh,255,cv.THRESH_BINARY)
dKernel = np.ones((12,12),np.uint8)
opened = cv.morphologyEx(thresholded, cv.MORPH_CLOSE, dKernel)