Opencv Image Manipulation To Crop An Angled Section Of An Image In Python
Solution 1:
Here's a image extraction widget that allows you to rotate the image and select a ROI by clicking and dragging the mouse. The idea is to use the mouse to select the bounding box window where we can use Numpy slicing to crop the image. Since OpenCV does not let you draw an angled rectangle, you can bypass that by first rotating the image.
Once you have selected the ROI, you can then crop the image using the bounding box coordinates. If we consider (0,0)
as the top left corner of the image with left-to-right as the x-direction and top-to-bottom as the y-direction and we have (x1, y1)
as the top-left vertex and (x2,y2)
as the bottom-right vertex of a ROI, we can crop the image by:
ROI = image[y1:y2, x1:x2]
We are able to do this since images are stored as a Numpy array in OpenCV. Here is a great resource for Numpy array indexing and slicing.
To use the widget:
left mouse click + drag
- select ROIright mouse click
- reset imager
- rotate image clockwise 5 degreese
- rotate image counter-clockwise 5 degreesc
- crop selected ROIq
- quit program
import cv2
import numpy as np
classExtractImageWidget(object):
def__init__(self):
self.original_image = cv2.imread('plane.PNG')
# Resize image, remove if you want raw image size
self.original_image = cv2.resize(self.original_image, (640, 556))
self.clone = self.original_image.copy()
cv2.namedWindow('image')
cv2.setMouseCallback('image', self.extract_coordinates)
# Bounding box reference points and boolean if we are extracting coordinates
self.image_coordinates = []
self.angle = 0
self.extract = False
self.selected_ROI = Falsedefextract_coordinates(self, event, x, y, flags, parameters):
# Record starting (x,y) coordinates on left mouse button clickif event == cv2.EVENT_LBUTTONDOWN:
self.image_coordinates = [(x,y)]
self.extract = True# Record ending (x,y) coordintes on left mouse bottom releaseelif event == cv2.EVENT_LBUTTONUP:
self.image_coordinates.append((x,y))
self.extract = False
self.selected_ROI = True
self.crop_ROI()
# Draw rectangle around ROI
cv2.rectangle(self.clone, self.image_coordinates[0], self.image_coordinates[1], (0,255,0), 2)
cv2.imshow("image", self.clone)
# Clear drawing boxes on right mouse button click and reset angleelif event == cv2.EVENT_RBUTTONDOWN:
self.clone = self.original_image.copy()
self.angle = 0
self.selected_ROI = Falsedefshow_image(self):
return self.clone
defrotate_image(self, angle):
# Grab the dimensions of the image and then determine the center
(h, w) = self.original_image.shape[:2]
(cX, cY) = (w / 2, h / 2)
self.angle += angle
# grab the rotation matrix (applying the negative of the# angle to rotate clockwise), then grab the sine and cosine# (i.e., the rotation components of the matrix)
M = cv2.getRotationMatrix2D((cX, cY), -self.angle, 1.0)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])
# Compute the new bounding dimensions of the image
nW = int((h * sin) + (w * cos))
nH = int((h * cos) + (w * sin))
# Adjust the rotation matrix to take into account translation
M[0, 2] += (nW / 2) - cX
M[1, 2] += (nH / 2) - cY
# Perform the actual rotation and return the image
self.clone = cv2.warpAffine(self.original_image, M, (nW, nH))
self.selected_ROI = Falsedefcrop_ROI(self):
if self.selected_ROI:
self.cropped_image = self.clone.copy()
x1 = self.image_coordinates[0][0]
y1 = self.image_coordinates[0][1]
x2 = self.image_coordinates[1][0]
y2 = self.image_coordinates[1][1]
self.cropped_image = self.cropped_image[y1:y2, x1:x2]
print('Cropped image: {} {}'.format(self.image_coordinates[0], self.image_coordinates[1]))
else:
print('Select ROI to crop before cropping')
defshow_cropped_ROI(self):
cv2.imshow('cropped image', self.cropped_image)
if __name__ == '__main__':
extract_image_widget = ExtractImageWidget()
whileTrue:
cv2.imshow('image', extract_image_widget.show_image())
key = cv2.waitKey(1)
# Rotate clockwise 5 degreesif key == ord('r'):
extract_image_widget.rotate_image(5)
# Rotate counter clockwise 5 degreesif key == ord('e'):
extract_image_widget.rotate_image(-5)
# Close program with keyboard 'q'if key == ord('q'):
cv2.destroyAllWindows()
exit(1)
# Crop imageif key == ord('c'):
extract_image_widget.show_cropped_ROI()
Post a Comment for "Opencv Image Manipulation To Crop An Angled Section Of An Image In Python"