Last active
October 1, 2020 21:03
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*********************************************************************** | |
* \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