-1

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)

enter image here

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.

coffeewin
  • 182
  • 3
  • 6
  • 26
  • @bechirjamoussi you have a tool in the text editor of SO to put your text as code. Text with a tabulation before each line will be formatted as code. – Clément Jul 29 '19 at 11:27
  • Possible duplicate of [How to crop an image in OpenCV using Python](https://stackoverflow.com/questions/15589517/how-to-crop-an-image-in-opencv-using-python) – T A Jul 29 '19 at 11:42

2 Answers2

3

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
singrium
  • 2,746
  • 5
  • 32
  • 45
0

You may try this:

x, y = [], []

for contour_line in contours:
    for contour in contour_line:
        x.append(contour[0][0])
        y.append(contour[0][1])

x1, x2, y1, y2 = min(x), max(x), min(y), max(y)

cropped = img[y1:y2, x1:x2]

Source: https://stackoverflow.com/questions/41069831/opencv-python-crop-image-using-numpy-array?rq=1#=