如何将图像分割为M x N个瓦片

  • 本文关键字:图像分割 c++ opencv
  • 更新时间 :
  • 英文 :


如何使用OpenCV和C++将Mat对象/图像拆分为M x N个相等的片段,并将这些片段从左到右、从上到下存储到Mat向量中?

非常感谢

与这里给出的相反问题的解决方案内联,这应该可以做到:

#include <opencv2/opencv.hpp>
std::vector<cv::Mat> splitImage( cv::Mat & image, int M, int N )
{
// All images should be the same size ...
int width  = image.cols / M;
int height = image.rows / N;
// ... except for the Mth column and the Nth row
int width_last_column = width  + ( image.cols % width  );
int height_last_row   = height + ( image.rows % height );
std::vector<cv::Mat> result;
for( int i = 0; i < N; ++i )
{
for( int j = 0; j < M; ++j )
{
// Compute the region to crop from
cv::Rect roi( width  * j,
height * i,
( j == ( M - 1 ) ) ? width_last_column : width,
( i == ( N - 1 ) ) ? height_last_row   : height );
result.push_back( image( roi ) );
}
}
return result;
}

int main()
{
cv::Mat image = cv::imread( "image.png" );
std::vector<cv::Mat> array_of_images = splitImage( image, 3, 2 );
for( int i = 0; i < array_of_images.size(); ++i )
{
cv::imshow( "Image " + std::to_string( i ), array_of_images[i] );
}
cv::waitKey( 0 );
}

这里有一个例子:

您在循环中一个接一个地拍摄矩形,并使用crop从全貌中捕捉选定的部分。

请注意,完整的图片可能没有被完美地分割,所以每行/每列中的一部分可能比其他部分略大。

#include <opencv2/opencv.hpp>
#include <highgui.h>
#include <iostream>
#include <string>
#include <vector>
//usage: app pic.ext M N
int main(int argc, char* argv[])
{
int M=0,N=0;

M = std::stoi(argv[2]);
N = std::stoi(argv[3]);

cv::Mat img = cv::imread(argv[1]);
if (img.empty())
{
std::cout << "failed to open the image" << std::endl;
return -1;        
}
std::vector<std::vector<cv::Mat>> result;
/* Regular size */
int crop_width = img.size().width / M;
int crop_height = img.size().height / N;
/* column / row first part size when part size is not evenly divided*/
int crop_width1 = img.size().width - (M-1)*crop_width;
int crop_height1 = img.size().height - (N-1)*crop_height;

int offset_x = 0;
int offset_y = 0;
for(int i = 0; i < M; i++) //rows
{
std::vector<cv::Mat> tmp;
offset_x = 0;
for(int j=0; j< N; j++) //columns
{
cv::Rect roi;
roi.x = offset_x;
roi.y = offset_y 
roi.width = (j>0) ? crop_width :  crop_width1;
roi.height = (i>0) ? crop_height : crop_height1;
offset_x += roi.width;
/* Crop the original image to the defined ROI */
cv::Mat crop = img(roi);
/* You can save part to a file: */
//cv::imwrite(std::to_string(i) + "x" + std::to_string(j)+".png", crop);
tmp.push_back(crop);


}
result.push_back(tmp);
offset_y += (i>0) crop_height : crop_height1; 
}
return 0;
}

最新更新