利⽤OpenCV
对图像进⾏裁剪
本⽂中我们讨论了利⽤ C++, Python对图像进⾏剪切的基本⽅法, 这些⽅法都是应⽤了对于矩阵的切⽚操作完成的。指定剪切图⽚在图像数据矩阵中对应的⾼、宽的范围,对应范围的数据代表了切割出来的图像。通过 imwirte, imshow 可以将切割下的图⽚进⾏存储和显⽰。 后⾯也进⼀步讨论了如何对⼤的
图⽚进⾏分割,形成许多⼩的图⽚的⽅法。
关键词: 图⽚剪切,crop
本⽂来⾃于 中对于OpenCV中裁剪图⽚⽅法的介绍。
§00 前 ⾔
好了,为了你⾃⼰的需要,让我们看看如何应⽤OpenCV来裁剪⼀个图像。
0.1 为什么需要图像裁剪?
⾸先,为什么我们需要对图像进⾏裁剪?
裁剪图像是将图⽚中不需要的部分去掉,或者对图⽚中重要的部分进⾏凸显。
0.2 OpenCV如何完成图⽚裁剪的?
在OpenCV中并没有⽤于裁剪图⽚的特殊函数,⽽是通过NumPy 矩阵的切⽚功能来完成对于图⽚的裁剪的。每⼀个被读⼊计算机内存的图⽚都是存储在2D的矩阵(每⼀个颜⾊通道都是存储在2D矩阵,⼀个图⽚可能包含有三个颜⾊通道)。只需要指明需要裁剪下来的区域对应的像素的⾼宽位置,我们就可以办到了。
0.3 样例代码
下⾯的代码⽚段演⽰了在Python,C++中如何完成图⽚的裁剪的。在本⽂的后⾯将会对他们进⾏详细的介绍。如果你仅仅希望参照⼀些可执⾏的样例完成你⼿头的⼯作,看看这些代码也就够了。
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(80,280), Range(150,330));
//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();
return0;
}
0.4 所需要软件包或者头⽂件
Python
# Importing the cv2 library
import cv2
C++
#include<opencv2/opencv.hpp>
#include<iostream>
// Namespace nullifies the use of cv::function();
using namespace std;
using namespace cv;
§01 图⽚裁剪
下⾯这个图⽚就是后⾯代码中所使⽤的图⽚样例。
▲ 图4.1 后⾯软件样例中所使⽤的图⽚
▲图4.1 后⾯软件样例中所使⽤的图⽚
rectangle函数opencv1.1 读⼊图⽚
Python
img=cv2.imread('test.png')
# Prints Dimensions of the image
print(img.shape)
# Display the image
cv2.imshow("original", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
C++
Mat img = imread("test.jpg");
//Print the height and width of the image
cout <<"Width : "<< img.size().width << endl;
cout <<"Height: "<< img.size().height << endl;
cout <<"Channels: "<< img.channels()<< endl;
// Display image
imshow("Image", img);
waitKey(0);
destroyAllWindows();
上⾯的代码将图⽚读⼊计算机并进⾏显⽰,包括显⽰图⽚的尺⼨。 图⽚的尺⼨不仅仅包括宽、⾼,也包括有图⽚的颜⾊通道数量,⽐如对于RGB彩⾊图像它就包括有三个颜⾊通道:红、绿、蓝。
1.2 图⽚裁剪
下⾯进⾏图⽚的裁剪,将包含有花朵的部分裁剪下来。
Python
cropped_image = img[80:280,150:330]# Slicing to crop the image
# Display the cropped image
cv2.imshow("cropped", cropped_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
C++
Mat crop = img(Range(80,280),Range(150,330));// Slicing to crop the image
// Display the cropped image
imshow("Cropped Image", crop);
waitKey(0);
destroyAllWindows();
return0;
▲图1.2.1 图⽚裁剪后的结果
在Python程序中,你使⽤的NumPy矩阵的切⽚来完成图⽚的裁剪。对于矩阵的切⽚,你需要指明对于矩阵索引的起始和结束的索引数值,包括第⼀个和第⼆个坐标轴。
通常情况下,第⼀个坐标表⽰了图像的⾼度;
第⼆个坐标轴表⽰了图像的宽度;
如果按照传统的⽅式,⽤⼆维矩阵来表⽰图⽚,第⼀个坐标代表着矩阵的 ⾏(在图像中⾏代表了图⽚的Y轴的⽅向),那么如何应⽤NumPy矩阵的切⽚来完成图⽚的裁剪呢?下⾯给出了对应的代码⽚段。
cropped = img[start_row:end_row, start_col:end_col]
在C++中,我们使⽤了 Range() 函数了对图⽚进⾏裁剪:
与Python⼀样,也是使⽤了切⽚操作;
同样,图⽚表⽰为2D矩阵,采⽤相同坐标定义⽅式。
下⾯就是在C++vs完成对图⽚进⾏裁剪的语法:
img(Range(start_row, end_row), Range(start_col, end_col))
§02 分割图⽚
在应⽤中,我们时常需要把⼀个⼤图分割成很多⼩的图⽚。 在OpenCV中提供了这样的⽅法。 使⽤⼀个循环来吧⼀个⼤图中的不同部位分割成⼀些⼩的图像块。 有限需要获得图⽚的尺⼨以及图像块的⼤⼩。
Python
img = cv2.imread("test_cropped.jpg")
image_copy = py()
imgheight=img.shape[0]
imgwidth=img.shape[1]
C++
Mat img = imread("test_cropped.jpg");
Mat image_copy = img.clone();
int imgheight = ws;
int imgwidth = ls;
载⼊宽和⾼数值,来指明图⽚中那个范围内需要被剪切下来。 在Python中可以使⽤ range() 函数。下载吗通过两重循环来完成图像切割。
1. 第⼀重循环是在宽度⽅向上;
2. 第⼆重循环是在⾼度⽅向上;
2.1 分割图像的代码
下⾯我们将图像分割成76×104(宽×⾼)的图像⼩块,步长(也就是在图像上移动的像素个数)在内循环和外循环(对应的宽和⾼)是相同的。
Python
M =76
N =104
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('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
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('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
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('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
else:
#Crop into patches of size MxN
tiles = image_copy[y:y+M, x:x+N]
#Save each patch into file directory
cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
C++
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论