Opencv basics cropping images using OpenCV

Keywords: Python C++ OpenCV

First, why do we need crops? Clipping is to remove all unnecessary objects or areas from the image or to highlight a special feature of the image.

Unlike Numpy, which uses slicing to achieve clipping, OpenCV does not have a specific function to perform clipping. Each image read is stored in a 2D array (for each color channel). Just specify the height and width (in pixels) of the area to be cropped.

1. Simple version code implementation

The following code snippet shows how to crop images using Python and c + +. You will learn more about this in a later article.
(1)Python

# Import related packages
import cv2
import numpy as np

img = cv2.imread('test.jpg')
print(img.shape) # Print image shape
cv2.imshow("original", img)

# Crop image
cropped_image = img[80:280, 150:330]

# Show crop image
cv2.imshow("cropped", cropped_image)

# Save crop image
cv2.imwrite("Cropped Image.jpg", cropped_image)

cv2.waitKey(0)
cv2.destroyAllWindows()

(2)C++

// Include library files
#include<opencv2/opencv.hpp>
#include<iostream>

// Namespace
using namespace std;
using namespace cv;

int main()
{
	// Read image
	Mat img = imread("test.jpg");
	cout << "Width : " << img.size().width << endl;
	cout << "Height: " << img.size().height << endl;
	cout<<"Channels: :"<< img.channels() << endl;
	// Crop image
	Mat cropped_image = img(Range(80,280), Range(150,330));

	//Show crop image
	imshow(" Original Image", img);
	imshow("Cropped Image", cropped_image);

	//Save crop image
	imwrite("Cropped Image.jpg", cropped_image);

	// Wait for any key input before exiting
	waitKey(0);
	destroyAllWindows();
	return 0;
}

2. Code analysis

In Python, the image is cropped in the same way as the NumPy array slice. To slice an array, you need to specify the start and end indexes of the first and second dimensions.

  • The first dimension is the number of rows or height of the image.
  • The second dimension is the number of columns or width of the image.

By convention, the first dimension of a 2D array represents the rows of the array (where each row represents the y coordinate of the image). How to slice a NumPy array? Look at the syntax in this example: cropped = img[start_row:end_row, start_col:end_col]

In c + +, we use the Range() function to crop the image.

  • Like Python, it also applies slicing.
  • Here, the image is also read in as a 2D matrix, following the Convention described above.

The following is the c + + syntax for cropping images: img(Range(start_row, end_row), Range(start_col, end_col))

3. Use clipping to segment the image into small pieces

A practical application of clipping in OpenCV is to segment an image into smaller blocks. Use the loop to crop a clip from the image.
(1) Python

# Import related packages
import cv2
import numpy as np
img =  cv2.imread("test.png")
image_copy = img.copy() 
imgheight=img.shape[0]
imgwidth=img.shape[1]

M = 83
N = 124
x1 = 0
y1 = 0

for y in range(0, imgheight, M):
    for x in range(0, imgwidth, N):
        if (imgheight - y) < M or (imgwidth - x) < N:
            break
            
        y1 = y + M
        x1 = x + N

        # Check whether the coordinates of the block exceed the width or height of the image
        if x1 >= imgwidth and y1 >= imgheight:
            x1 = imgwidth - 1
            y1 = imgheight - 1
            #Cut into small pieces of MxN
            tiles = image_copy[y:y1, x:x1]
            #Save each block to a file directory
            cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
        elif y1 >= imgheight: # When the block height exceeds the image height
            y1 = imgheight - 1
            #Cut into blocks of size MxN
            tiles = image_copy[y:y+M, x:x+N]
            #Save each block to a file directory
            cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
        elif x1 >= imgwidth: # When the block width exceeds the image width
            x1 = imgwidth - 1
            #Cut into blocks of size MxN
            tiles = image_copy[y:y+M, x:x+N]
            #Save each block to a file directory
            cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
        else:
            #Cut into blocks of size MxN
            tiles = image_copy[y:y+M, x:x+N]
            #Save each block to a file directory
            cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
#Save the entire image to the file directory
cv2.imshow("Patched Image",img)
cv2.imwrite("patched.jpg",img)
 
cv2.waitKey()
cv2.destroyAllWindows()

(2)C++

// Include library files
#include<opencv2/opencv.hpp>
#include<iostream>

// Namespace
using namespace std;
using namespace cv;

int main()
{
	Mat img = imread("test.png");
	Mat image_copy = img.clone();
	int imgheight = img.rows;
	int imgwidth = img.cols;
	int M = 83;
	int N = 124;
	
	int x1 = 0;
	int y1 = 0;
	for (int y = 0; y<imgheight; y=y+M)
	{
	    for (int x = 0; x<imgwidth; x=x+N)
	    {
	        if ((imgheight - y) < M || (imgwidth - x) < N)
	        {
	            break;
	        }
	        y1 = y + M;
	        x1 = x + N;
	        string a = to_string(x);
	        string b = to_string(y);
	
	        if (x1 >= imgwidth && y1 >= imgheight)
	        {
	            x = imgwidth - 1;
	            y = imgheight - 1;
	            x1 = imgwidth - 1;
	            y1 = imgheight - 1;
	
	            // Cut into blocks of size MxN
	            Mat tiles = image_copy(Range(y, imgheight), Range(x, imgwidth));
	            //Save each block to a file directory
	            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
	            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
	        }
	        else if (y1 >= imgheight)
	        {
	            y = imgheight - 1;
	            y1 = imgheight - 1;
	
	            // Cut into blocks of size MxN
	            Mat tiles = image_copy(Range(y, imgheight), Range(x, x+N));
	            //Save each block to a file directory
	            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
	            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
	        }
	        else if (x1 >= imgwidth)
	        {
	            x = imgwidth - 1;   
	            x1 = imgwidth - 1;
	
	            // Cut into blocks of size MxN
	            Mat tiles = image_copy(Range(y, y+M), Range(x, imgwidth));
	            //Save each block to a file directory
	            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
	            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
	        }
	        else
	        {
	            // Cut into blocks of size MxN
	            Mat tiles = image_copy(Range(y, y+M), Range(x, x+N));
	            //Save each block to a file directory
	            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
	            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
	        }
	    }
	}
	imshow("Patched Image", img);
	imwrite("patched.jpg",img);
	waitKey();
	destroyAllWindows();
	return 0;
}

4. Some interesting applications using clipping

  • You can use clipping to extract the region of interest from the image and discard other parts that you don't need to use.
  • You can extract small blocks from the image to train a small block based neural network.

summary

In this blog, we discussed the basic syntax for cropping images in c + + and Python. The clipping operation is carried out through slicing, that is, we specify the height and width or area to be clipped as the dimension of the image matrix. Therefore, the generated image can be saved in a new matrix or by updating the existing matrix. The matrix can then be displayed as an image using the OpenCV imshow() function or written to disk as a file using the OpenCV imwrite() function. We also discussed how to segment an image into smaller blocks and some applications around it.

Reference catalogue

https://learnopencv.com/cropping-an-image-using-opencv/

Posted by rebelo on Wed, 22 Sep 2021 17:23:28 -0700