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.

Importing Libraries

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.

Initialising Variables

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[0]:
         d= img.shape[0]-y
         
    if x+ w>img.shape[1]    :
        w= img.shape[1]-x
        
    cropped_img= img[y :y+ d, x: x+ w]
    return cropped_img
Cropped image

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.

Horizontal flip

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
Horizonatal flip

Vertical flip

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
Vertical Flip

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
Flipping on both sides

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] )

Parameters:
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
90 degrees rotated image

Undo Operation

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.

Undo 1
Undo 2

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)

Implementation

Conclusion

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.

-Suniti Jain


0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

Insert math as
Block
Inline
Additional settings
Formula color
Text color
#333333
Type math using LaTeX
Preview
\({}\)
Nothing to preview
Insert