• OpenCV入门(C++/Python)-使用OpenCV裁剪图像(四)


    裁剪是为了从图像中删除所有不需要的物体或区域。甚至突出显示图像的特定功能。

    使用OpenCV裁剪没有特定的功能,NumPy数组切片是工作。读取的每个图像都存储在2D数组中(对于每个颜色通道)。只需指定要裁剪区域的高度和宽度(以像素为单位),就可以完成

    1.使用OpenCV裁剪

    以下代码片段展示了如何使用Python和C++裁剪图像。在例子的进一步,您将详细了解这些。
    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    C++

    // Include Libraries
    #include
    #include
     
    // 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    上面的代码读取并显示图像及其尺寸。尺寸不仅包括二维矩阵的宽度和高度,还包括通道的数量(例如,RGB图像有3个通道——红色、绿色和蓝色)。

    让我们尝试裁剪图像中包含美女的部分。

    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() 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    在Python中,您可以使用与NumPy数组切片相同的方法裁剪图像。要切片数组,您需要指定第一维和第二维的开始和结束索引。

    • 第一个维度总是行数或图像的高度。
    • 第二个维度是列数或图像的宽度。

    如何剪切图像的NumPy数组?查看此示例中的语法:

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

    在C++中,我们使用Range()函数裁剪图像。

    • Python同理一样,它也应用切片。
    • 在这里,图像也按照上述相同的约定作为二维矩阵读取。

    以下是裁剪图像的C++语法:

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

    2.使用裁剪功能对图像进行划分

    在OpenCV中裁剪的一个实际应用可以是将图像划分为大小相同图像块。使用循环从图像中裁剪片段。首先从图像的形状中获取所需图像块的高度和宽度

    Python

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

    C++

    Mat img = imread("test_cropped.jpg");
    Mat image_copy = img.clone();
    int imgheight = img.rows;
    int imgwidth = img.cols;
    
    • 1
    • 2
    • 3
    • 4

    加载高度和宽度,以指定需要裁剪较小图像块的范围。为此,使用Python中的range()函数。现在,使用两个循环裁剪:

    • 宽度范围
    • 高度范围

    已知原图像瘩高度宽度为(1350,1080),我们使用的图像块的高度和宽度分别为(270,216)。内外循环的步幅(我们在图像中移动的像素数)也就是划分下来,有25个图像块。(拼图一样)

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    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);    
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    接下来,使用imshow()函数显示图像块拼图。使用imwrite()函数将其保存到文件目录中。

    Python

    #Save full image into file directory
    cv2.imshow("Patched Image",img)
    cv2.imwrite("patched.jpg",img)
      
    cv2.waitKey()
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    C++

    imshow("Patched Image", img);
    imwrite("patched.jpg",img);
    waitKey();
    destroyAllWindows();
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    Python

    C++

  • 相关阅读:
    MybatisPlus主键生成策略与自动填充
    后疫情时代新加坡网络安全治理的动态与趋势
    【数据可视化】第四章—— 基于pandas的数据可视化(pandas数据结构)
    vue项目获取视频封面展示在页面上
    Nova组件源码分析之冷迁移与Resize
    TCP三次握手、四次挥手
    如何计算 InnDB 最大记录总数
    问题: 视频颜色问题,偏绿
    Windows下pm2调用npm和nuxt的办法
    Spring - 3 ( 12000 字 Spring 入门级教程 )
  • 原文地址:https://blog.csdn.net/weixin_42010722/article/details/128183509