Skip to content

Instantly share code, notes, and snippets.

@SuperKogito
Last active October 1, 2020 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SuperKogito/0d6f839a04f17999aad8e4eac87f2411 to your computer and use it in GitHub Desktop.
Save SuperKogito/0d6f839a04f17999aad8e4eac87f2411 to your computer and use it in GitHub Desktop.
code for my blog post <https://superkogito.github.io/blog/DivideImageUsingOpenCv.html> a snippet for dividing image into blocks
/***********************************************************************
* \file DivideImageUsingOpenCv.cpp
* \brief divide image into multiple blocks using OpenCV.
*
* \author SuperKogito
* \date October 2020
*
* @note:
* references and sources:
* - https://answers.opencv.org/question/53694/divide-an-image-into-lower-regions/
* - https://graphicdesign.stackexchange.com/questions/30008/crop-a-big-picture-into-several-small-size-pictures
***********************************************************************/
#include <Windows.h>
#include <opencv2/opencv.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/core/utils/filesystem.hpp>
using namespace std;
using namespace cv;
int divideImage(const cv::Mat& img, const int blockWidth, const int blockHeight, std::vector<cv::Mat>& blocks)
{
// Checking if the image was passed correctly
if (!img.data || img.empty())
{
std::wcout << "Image Error: Cannot load image to divide." << std::endl;
return EXIT_FAILURE;
}
// init image dimensions
int imgWidth = img.cols;
int imgHeight = img.rows;
std::wcout << "IMAGE SIZE: " << "(" << imgWidth << "," << imgHeight << ")" << std::endl;
// init block dimensions
int bwSize;
int bhSize;
int y0 = 0;
while (y0 < imgHeight)
{
// compute the block height
bhSize = ((y0 + blockHeight) > imgHeight) * (blockHeight - (y0 + blockHeight - imgHeight)) + ((y0 + blockHeight) <= imgHeight) * blockHeight;
int x0 = 0;
while (x0 < imgWidth)
{
// compute the block height
bwSize = ((x0 + blockWidth) > imgWidth) * (blockWidth - (x0 + blockWidth - imgWidth)) + ((x0 + blockWidth) <= imgWidth) * blockWidth;
// crop block
blocks.push_back(img(cv::Rect(x0, y0, bwSize, bhSize)).clone());
// update x-coordinate
x0 = x0 + blockWidth;
}
// update y-coordinate
y0 = y0 + blockHeight;
}
return EXIT_SUCCESS;
}
int main()
{
// init vars
const int blockw = 128;
const int blockh = 128;
std::vector<cv::Mat> blocks;
// read png image
Mat image = cv::imread("Lenna.png", IMREAD_UNCHANGED);
cv::imshow("Display window", image);
// divide image into multiple blocks
int divideStatus = divideImage(image, blockw, blockh, blocks);
// debug: save blocks
cv::utils::fs::createDirectory("blocksFolder");
for (int j = 0; j < blocks.size(); j++)
{
std::string blockId = std::to_string(j);
std::string blockImgName = "blocksFolder/block#" + blockId + ".png";
imwrite(blockImgName, blocks[j]);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment