首先,为什么我们需要作物?裁剪是为了从图像中移除所有不需要的物体或区域或者是突出图像的一个特殊特征。

与Numpy使用切片操作实现裁剪不同,OpenCV没有特定的函数来进行裁剪操作。读取的每个图像都存储在一个2D数组中(对于每个颜色通道)。只需指定要裁剪的区域的高度和宽度(以像素为单位)即可。

1.简单版本代码实现

下面的代码片段展示了如何使用Python和c++裁剪图像。在后面的文章中,你将会更详细地了解这些。
(1)Python

# 导入相关包
import cv2
import numpy as npimg = cv2.imread('test.jpg')
print(img.shape) # Print image shape
cv2.imshow("original", img)# 裁剪图像
cropped_image = img[80:280, 150:330]# 显示裁剪图像
cv2.imshow("cropped", cropped_image)# 保存裁剪图像
cv2.imwrite("Cropped Image.jpg", cropped_image)cv2.waitKey(0)
cv2.destroyAllWindows()

(2)C++

// 包含库文件
#include<opencv2/opencv.hpp>
#include<iostream>// 命名空间
using namespace std;
using namespace cv;int main()
{// 读取图像Mat img = imread("test.jpg");cout << "Width : " << img.size().width << endl;cout << "Height: " << img.size().height << endl;cout<<"Channels: :"<< img.channels() << endl;// 裁剪图像Mat cropped_image = img(Range(80,280), Range(150,330));//显示裁剪图像imshow(" Original Image", img);imshow("Cropped Image", cropped_image);//保存裁剪图像imwrite("Cropped Image.jpg", cropped_image);// 等待任意键输入才退出waitKey(0);destroyAllWindows();return 0;
}

2.代码解析

在Python中,使用与NumPy数组切片相同的方法裁剪图像。要对数组进行切片,需要指定第一个维度和第二个维度的开始和结束索引。

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

按照惯例,2D数组的第一维表示数组的行(其中每一行表示图像的y坐标)。如何切片一个NumPy数组?看看这个例子中的语法:cropped = img[start_row:end_row, start_col:end_col]

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

  • 与Python一样,它也应用了切片。
  • 在这里,图像也是作为2D矩阵读入的,遵循上面描述的约定。

下面是裁剪图像的c++语法:img(Range(start_row, end_row), Range(start_col, end_col))

3. 使用裁剪将图像分割成小块

OpenCV中裁剪的一个实际应用是将图像分割成更小的块。使用循环从图像中裁剪出一个片段。
(1) Python

# 导入相关包
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 = 0for y in range(0, imgheight, M):for x in range(0, imgwidth, N):if (imgheight - y) < M or (imgwidth - x) < N:breaky1 = y + Mx1 = x + N# 检查块的坐标是否超过图像的宽度或高度if x1 >= imgwidth and y1 >= imgheight:x1 = imgwidth - 1y1 = imgheight - 1#切成大小为MxN的小块tiles = image_copy[y:y1, x:x1]#将每个块保存到文件目录中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: # 当块高度超过图像高度时y1 = imgheight - 1#裁切成大小为MxN的块tiles = image_copy[y:y+M, x:x+N]#将每个块保存到文件目录中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: # 当块宽度超过图像宽度时x1 = imgwidth - 1#裁切成大小为MxN的块tiles = image_copy[y:y+M, x:x+N]#将每个块保存到文件目录中cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)else:#裁切成大小为MxN的块tiles = image_copy[y:y+M, x:x+N]#将每个块保存到文件目录中cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
#将整张图象保存到文件目录中
cv2.imshow("Patched Image",img)
cv2.imwrite("patched.jpg",img)cv2.waitKey()
cv2.destroyAllWindows()

(2)C++

// 包含库文件
#include<opencv2/opencv.hpp>
#include<iostream>// 命名空间
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;// 裁切成大小为MxN的块Mat tiles = image_copy(Range(y, imgheight), Range(x, imgwidth));//将每个块保存到文件目录中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;// 裁切成大小为MxN的块Mat tiles = image_copy(Range(y, imgheight), Range(x, x+N));//将每个块保存到文件目录中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;// 裁切成大小为MxN的块Mat tiles = image_copy(Range(y, y+M), Range(x, imgwidth));//将每个块保存到文件目录中imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    }else{// 裁切成大小为MxN的块Mat tiles = image_copy(Range(y, y+M), Range(x, x+N));//将每个块保存到文件目录中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.使用裁剪的一些有趣应用

  • 可以使用裁剪从图像中提取感兴趣的区域,并丢弃不需要使用的其他部分。
  • 你可以从图像中提取小块来训练基于小块的神经网络。

总结

在这篇博客中,我们讨论了用c++和Python裁剪图像的基本语法。裁剪操作是通过切片来进行的,即我们指定要裁剪的高度和宽度或区域作为图像矩阵的维数。因此,生成的图像可以保存在一个新的矩阵中,或者通过更新现有的矩阵来保存。然后可以使用OpenCV imshow()函数将这个矩阵显示为图像,或者使用OpenCV imwrite()函数将其作为文件写入磁盘。我们还讨论了如何将图像分割成更小的块,以及围绕它的一些应用程序。

参考目录

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

OpenCV基础(4)使用OpenCV裁剪图像相关推荐

  1. c++ opencv实现区域填充_Python+OpenCV基础教程2:平滑图像

    学习模糊/平滑图像,消除噪点.图片等可到源码处下载. 01 目标 02 教程 滤波与模糊 推荐大家先阅读:番外篇:卷积基础(图片边框),有助于理解卷积和滤波的概念. 关于滤波和模糊,很多人分不清,我来 ...

  2. OpenCV基础八:OpenCV在各操作系统平台上的使用(陆续更新)

    八. 平台 鼠标 OpenCV通过回调函数使用鼠标,以下为定义回调函数必须匹配的协议: void your_mouse_callback(int event, //事件类型int x, //鼠标事件的 ...

  3. Opencv 基础(三):使用OpenCV裁剪图像

    裁剪是从图像中移除所有不需要的物体或区域.甚至可以突出显示图像的特定特征. 没有使用OpenCV进行裁剪的特定函数,NumPy数组切片是做这项工作的.读取的每个图像都存储在一个2D数组中(对于每个颜色 ...

  4. 【OpenCV 例程200篇】09. 图像的裁剪(cv2.selectROI)

    [OpenCV 例程200篇]09. 图像的裁剪(cv2.selectROI) 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持 ...

  5. 使用Python和OpenCV捕获鼠标事件,并裁剪图像

    使用Python和OpenCV捕获鼠标事件,并裁剪图像 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python和OpenCV捕获鼠标事件.还演示了如何快速裁剪和提取图像区域,这在为自己的自 ...

  6. [python opencv 计算机视觉零基础到实战] 六、图像运算

    一.学习目标 了解opencv中图像运算的方法 了解opencv中图像运算的运用 如有错误欢迎指出~ 二.了解OpenCV中图像运算的运用 目录 [python opencv 计算机视觉零基础到实战] ...

  7. OpenCV基础知识 图像

    OpenCV基础知识 图像 位图模式 灰度模式 RGB模式 位图模式 位图模式是是1位深度的图像,只有黑和白两种颜色.它可以由扫描或置入黑色的矢量线条图像生成,也能由灰度模式转换而成.其他图像模式不能 ...

  8. 在Python中使用OpenCV裁剪图像

    What is Cropping? 什么是播种? Cropping is the removal of unwanted outer areas from a photographic or illu ...

  9. 8.openCV 裁剪图像

    8.openCV 裁剪图像 一.使用 OpenCV 裁剪图像 二.项目结构和代码讲解 1.项目结构 2.代码讲解 三.代码下载 一.使用 OpenCV 裁剪图像 在本教程的第一部分,我们将讨论如何将 ...

最新文章

  1. 在raspberry的jessie版系统上安装opencv3.0
  2. cuda 核函数 for循环_【CUDA 基础】6.2 并发内核执行
  3. mysql 创建查询 删除_MYSQL数据库查询删除创建企业基本知识
  4. android 串口通信丢包,新手求教为什么串口接收数据总丢包
  5. 金属100寸“电视”却无屏,语音识别+DTS+1080P,微鲸M1测评
  6. CentOS 6.3 编译安装搭建LNMP(迎接端午节,首发)
  7. weui 必填_小程序开发WeUI填坑(一)
  8. HTTP协议和SOCKS5协议
  9. linux 单网卡 双网段,用单网卡连接两个网段
  10. js前端构造json对象后台接收并反序列化
  11. Arcpy ERROR 999999: 执行函数时出错解决方法
  12. ios开发中UIButton设置标题和图片不能同时显示问题解决
  13. 2014校园招聘_腾讯2014校园招聘
  14. 蓝桥杯——2021第十二届C/C++真题[省赛][B组]
  15. 虚拟主机怎么搭建网站(如何搭建自己虚拟主机)
  16. AT24C16页写和多页写
  17. python判断正数和负数教案_正数和负数教学设计
  18. 欢迎来到北工大换书网
  19. 2021年山东省安全员B证试题及解析及山东省安全员B证复审模拟考试
  20. 《当程序员的那些狗日日子》(五十七)迟来的爱恋

热门文章

  1. 2021年山阳中学高考成绩查询,陕西省山阳中学2018年高考成绩公布,2018年高考再创辉煌!...
  2. 分别使用正则表达式的子模式编号和子模式命名两种方法匹配ABAC、AABB、ABAB式成语
  3. 华为云存储服务分享文件的方法
  4. 【读书笔记】小狗钱钱
  5. 解决打开idea时候的Unmapped Spring configuration files found. Please configure Spring facet.警告
  6. 程序员的忧桑:有人向你反馈了一个Bug!
  7. 幻数java题_幻数
  8. tornado 自定义WEB框架 、与Tyrion组件做表单验证
  9. JavaScript中e.keycode详解
  10. Warren Krupsaw教你拍照:光线改变一切