Hola !! Have you ever wondered how fuzzy and time consuming image editing apps are? Wish if they were simpler and customizable? Wanna know how? Then, let’s go ahead and learn !!
Today, we are going to create a program that will let you resize, rotate and flip your images vertically and horizontally along with the facility of undoing your steps easily without hassle.
So let’s dive into the code.
In this code, we will ask the user to enter an image name. If the image doesn’t exist, we will re-prompt the user for the image until a certain number of times. Then, if image is found we will give user the options to edit his/her image with ability to undo or view it.
Here, user has options to resize image, rotate image, flip image, view image with the functionality to undo his actions.
import cv2 import datetime import os import sys
Loading the image
We have created a ask_image() function which takes image name as input and we’ll read the image cv2.read(). If image is not found or none and can’t be read after 5 attempts it will print the message “maximum limit reached” and program will be terminated. If the image is found, then it will append the image in stack and return the img and image_name. We will use the image for editing.
We will then define the count and stack variable for storing the limit function called and to store the images respectively. Then, we’ll ask the user to input image name.
count=0 stack= def ask_image(): ##user interaction print("enter the image name: ") img_name= input() global count img = cv2.imread(img_name) if img is None: if count==5: print("maximum limit reached re-run program") sys.exit() print(" no such image exits\n press 1 to reenter name \n press any other key to exit") x = input() if x=="1": count+=1 ask_image() else: sys.exit() else: stack.append(img) return [img, img_name]
I’ll be using the following image
Cropping the image
In order to crop the image, I have created the crop() function.
The function prompts the user to input four values which are x , y coordinates of the image and width, height respectively.
Then, we modify the height and width of image and return the resultant cropped image
def crop(img): x,y,w,d= map(int, input("enter the x-y coordinates , width and height\n").split()) if y+d>img.shape: d= img.shape-y if x+ w>img.shape : w= img.shape-x cropped_img= img[y :y+ d, x: x+ w] return cropped_img
Flipping the image
We will start flipping the images by calling the flip function from the cv2 module. As first input, this function receives the image to which we want to apply the flipping. As second input, it receives an integer representing the flip operation we want.
We can pass the following values to the second parameter:
- = 0 for flipping the image around the x-axis (vertical flipping)
- > 0 for flipping around the y-axis (horizontal flipping)
- < 0 for flipping around both axes.
So, we will start by flipping the image around the y-axis, by passing the value 1 as second argument of the flip function.
def flip_horizontal(img): img = cv2.flip(img, 1) #flip horizontally return img
Then, we will flip the image around the x-axis, by passing the value 0 as second argument of the flip function.
def flip_vertical(img): img = cv2.flip(img, 0) #flip vertically return img
Flipping around both axes
Then we will flip the image around both axes, by passing a value lesser than 0. We will use the value -1.
def flip_both_sides(img): img = cv2.flip(img, -1) #flip on both sides return img
Rotating the Image
cv2.rotate() method is used to rotate a 2D array in multiples of 90 degrees. The function cv::rotate rotates the array in three different ways.
Syntax: cv2.rotate( src, rotateCode[, dst] )
src: It is the image whose color space is to be changed.
rotateCode: It is an enum to specify how to rotate the array.
dst: It is the output image of the same size and depth as src image. It is an optional parameter.Return Value: It returns an image.
cv2.ROTATE_90_CLOCKWISE rotates the image by 90 degrees clockwise.
def rotate(img): #rotate 90 degrees img = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) return img
For undo operation, I’ll pop the last image added to the stack and will display the last element of stack. If the size of stack becomes 1, that means we are at our beginning point, i.e., the original image.
Function to ask user to input choice
We have created a choice() function that will take input and the following inputs will give the respective outputs as given below:
- if choice is 1, crop the image and save it in stack
- if choice is 2, flip the image horizontally and save it in stack
- if choice is 3, flip the image vertically and save it in stack
- if choice is 4, flip the image of both axes
- if choice is 5, then rotate the image
- if choice is 6, then undo the image by popping the last element out of stack
- if choice is 7, view image
- if another input is given, then save the image.
def choice(img,img_name): print(""" enter 1 to crop image\n enter 2 to flip horizontally\n enter 3 to flip vertically\n enter 4 to flip on both sides\n enter 5 to rotate \n enter 6 to undo\n enter 7 to view image\n enter any other key to exit and save""") x= input() if x=="1": curr= stack[-1] curr= crop(curr) stack.append(curr) view(curr) choice(img,img_name) elif x=="2": curr= stack[-1] curr= flip_horizontal(curr) stack.append(curr) view(curr) choice(img,img_name) elif x=="3": curr= stack[-1] curr=flip_vertical(curr) stack.append(curr) view(curr) choice(img,img_name) elif x=="4": curr= stack[-1] curr=flip_both_sides(curr) stack.append(curr) view(curr) choice(img,img_name) elif x=="5": curr= stack[-1] curr= rotate(curr) stack.append(curr) view(curr) choice(img,img_name) elif x=="6": if len(stack)== 1: print("invalid choice, you are at original image") choice(img,img_name) else: stack.pop() view(stack[-1]) choice(img,img_name) elif x=="7" : view(stack[-1]) choice(img,img_name) else: cv2.imwrite("edited"+img_name,stack[-1]) print(" file saved ") sys.exit()
Finally, we will be storing the values returned by ask_image function in img and img_name variables followed by calling the choice function which will take the input to perform the desired functionality on the image. (Refer ask_image and choice functions in the above blog for their description)
[img, img_name]= ask_image() choice(img, img_name)
Finally, we have implemented functions to edit images using OpenCV.
Try to execute these on you own. Let us know in the comment section what would you do differently.