Q:

Cropping an image after detecting the contours using opencv python

I'm trying to crop an image after detecting the contours and then extract information from it using python, opencv, and numpy.
Detecting the contours was successful but then I couldn't find a way to crop. I tried some code but I didn't get the result that I wanted:
import numpy as np
import cv2
image = cv2.imread('2.jpg') # Read in your image
blurred=cv2.blur(image,(23,51))#blur the image
gray=cv2.cvtColor(blurred,cv2.COLOR_BGR2GRAY)#gray scale
ret,threshold=cv2.threshold(gray , 2 , 255 , cv2.THRESH_BINARY+cv2.THRESH_OTSU)
contours,hierachy=cv2.findContours(threshold,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#detect contours
mask = np.zeros_like(image) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask,  contours,  0,  (0 ,0,255),1)
out = np.zeros_like(image) # Extract out the object and place into output image
out[mask == 255] = image[mask == 255]

# Now crop
mask=mask.transpose(2,0,1).reshape(-1,mask.shape[1])
(x, y) = np.where(mask == 255)
(topx, topy) = (np.min(x), np.min(y))
(bottomx, bottomy) = (np.max(x), np.max(y))
topx=topx
topy=topy
bottomx=bottomx
bottomy=bottomy
out = out[topx:bottomx,topy:bottomy]
print(out)

The array out is  empty which is weird because when I print topx, topy, bottomx, and bottomy, I get integers, so logically cropping would give me a result.

A:

Normally, if you have the contours detected, you can crop the contours by adding the following lines to your code, just after contours, hierarchy = cv2.findContours(threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE): 
i = 0
for c in contours:
    # get the bounding rect
    x, y, w, h = cv2.boundingRect(c)
    # to save the images
    cv2.imwrite('img_{}.jpg'.format(i), image[y:y+h,x:x+w])
    i += 1

