Getting started with OpenCV (C++/Python) - cropping images using OpenCV (4)

Cropping is to remove any unwanted objects or areas from an image. Even highlight specific features of an image.

There is no specific function for cropping with OpenCV, NumPy array slicing is the job. Each image read is stored in a 2D array (for each color channel). Just specify the height and width in pixels of the area you want to crop, and you're done

1. Cropping with OpenCV

The following code snippet shows how to crop an image using Python and C++. You'll learn about these in detail further down the example.
Python

# Import packages
import cv2
import numpy as np
 
img = cv2.imread('test.jpg')
print(img.shape) # Print image shape
cv2.imshow("original", img)
 
# Cropping an image
cropped_image = img[400:1200, 350:700]
 
# Display cropped image
cv2.imshow("cropped", cropped_image)
 
# Save the cropped image
cv2.imwrite("Cropped Image.jpg", cropped_image)
 
cv2.waitKey(0)
cv2.destroyAllWindows()

C++

// Include Libraries
#include<opencv2/opencv.hpp>
#include<iostream>
 
// Namespace nullifies the use of cv::function();
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(400,1200), Range(350,700));
 
  //display image
  imshow(" Original Image", img);
  imshow("Cropped Image", cropped_image);
 
  //Save the cropped Image
  imwrite("Cropped Image.jpg", cropped_image);
 
  // 0 means loop infinitely
  waitKey(0);
  destroyAllWindows();
  return 0;
}

The above code reads and displays the image and its dimensions. Dimensions include not only the width and height of the 2D matrix, but also the number of channels (for example, an RGB image has 3 channels - red, green and blue).

Let's try cropping the part of the image that contains the beautiful woman.

Python

cropped_image = img[400:1200, 350:700] # Slicing to crop the image
 
# Display the cropped image
cv2.imshow("cropped", cropped_image)
cv2.waitKey(0)
cv2.destroyAllWindows() 

C++

Mat crop = img(Range(400,1200),Range(350,700)); // Slicing to crop the image
 
// Display the cropped image
imshow("Cropped Image", crop);
 
waitKey(0);
destroyAllWindows();
return 0;

insert image description here
In Python, you can crop images in the same way as NumPy array slicing. To slice an array, you need to specify the start and end indices of the first and second dimensions.

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

How to crop a NumPy array of an image? Check out the syntax in this example:

cropped = img[start_row:end_row, start_col:end_col]

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

  • In the same way, Python also applies slices.
  • Here too, the image is read as a 2D matrix following the same convention as above.

Following is the C++ syntax for cropping an image:

img(Range(start_row, end_row), Range(start_col, end_col))

2. Use the cropping function to divide the image

A practical application of cropping in OpenCV can be to divide an image into equally sized image patches. Use a loop to crop a segment from an image. First get the height and width of the desired image block from the shape of the image

Python

img =  cv2.imread("test_cropped.jpg")
image_copy = img.copy() 
imgheight=img.shape[0]
imgwidth=img.shape[1]

C++

Mat img = imread("test_cropped.jpg");
Mat image_copy = img.clone();
int imgheight = img.rows;
int imgwidth = img.cols;

Load the height and width to specify the extent to which the smaller image tiles need to be cropped. For this, use the range() function in Python. Now, crop using two loops:

  • width range
  • height range

It is known that the height and width of the original image block are (1350, 1080), and the height and width of the image blocks we use are (270, 216) respectively. The stride of the inner and outer loops (the number of pixels we move in the image) is divided into 25 image blocks. (like a puzzle)

Python

M = 216
N = 270
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 patch width or height exceeds the image width or height
        if x1 >= imgwidth and y1 >= imgheight:
            x1 = imgwidth - 1
            y1 = imgheight - 1
            # Crop into patches of size MxN
            tiles = image_copy[y:y + M, x:x + N]
            # Save each patch into file directory
            cv2.imwrite(str(x) + '_' + str(y) + '.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
        elif y1 >= imgheight:  # when patch height exceeds the image height
            y1 = imgheight - 1
            # Crop into patches of size MxN
            tiles = image_copy[y:y + M, x:x + N]
            # Save each patch into file directory
            cv2.imwrite(str(x) + '_' + str(y) + '.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
        elif x1 >= imgwidth:  # when patch width exceeds the image width
            x1 = imgwidth - 1
            # Crop into patches of size MxN
            tiles = image_copy[y:y + M, x:x + N]
            # Save each patch into file directory
            cv2.imwrite(str(x) + '_' + str(y) + '.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
        else:
            # Crop into patches of size MxN
            tiles = image_copy[y:y + M, x:x + N]
            # Save each patch into file directory
            cv2.imwrite(str(x) + '_' + str(y) + '.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)

C++

int M = 216;
int N = 270;
 
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;
 
            // crop the patches of size MxN
            Mat tiles = image_copy(Range(y, imgheight), Range(x, imgwidth));
            //save each patches into 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;
 
            // crop the patches of size MxN
            Mat tiles = image_copy(Range(y, imgheight), Range(x, x+N));
            //save each patches into 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;
 
            // crop the patches of size MxN
            Mat tiles = image_copy(Range(y, y+M), Range(x, imgwidth));
            //save each patches into file directory
            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
        }
        else
        {
    
    
            // crop the patches of size MxN
            Mat tiles = image_copy(Range(y, y+M), Range(x, x+N));
            //save each patches into file directory
            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
        }
    }
}

Next, use the imshow() function to display the image tile mosaic. Save it to a file directory using the imwrite() function.

Python

#Save full image into file directory
cv2.imshow("Patched Image",img)
cv2.imwrite("patched.jpg",img)
  
cv2.waitKey()
cv2.destroyAllWindows()

C++

imshow("Patched Image", img);
imwrite("patched.jpg",img);
waitKey();
destroyAllWindows();

insert image description here

Python

C++

Guess you like

Origin blog.csdn.net/weixin_42010722/article/details/128183509
Recommended