Skip to content

Instantly share code, notes, and snippets.

@tractatus
Last active July 10, 2017 11: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 tractatus/adebf14b77b9e0f901a3bbd2814ae5ec to your computer and use it in GitHub Desktop.
Save tractatus/adebf14b77b9e0f901a3bbd2814ae5ec to your computer and use it in GitHub Desktop.
void createWeb::run(cv::Mat& sourceImage, cv::Mat& dstImage){
int tiers;
int height = sourceImage.rows;
int width = sourceImage.cols;
int maxdim = (width > height ? width : height);
tiers = (int)log2(maxdim/256);
if((maxdim/pow(2, tiers))>256){
tiers++;
}
int tileWidth = 256;
int tileHeight = 256;
int numberOfTiles = 0;
int tileGroupNumber = -1;
tiers++;
for (int tierInd = 0; tierInd < tiers; tierInd++){
double downsamplingfactor = 1/pow(2, tiers-1-tierInd);
resize(sourceImage, dstImage, Size(), downsamplingfactor, downsamplingfactor, INTER_CUBIC);
//how many row and col tiles
rows = (dstImage.rows / 256) + (dstImage.rows % 256 ? 1 : 0);
cols = (dstImage.cols / 256) + (dstImage.cols % 256 ? 1 : 0);
for (int rowTile = 0; rowTile < rows; rowTile++){
for(int colTile = 0; colTile < cols; colTile++){
if(numberOfTiles % 256 == 0){
tileGroupNumber++;
QString tileGroupNumberStr = QString::number(tileGroupNumber);
QString tilegrouppath;
tilegrouppath = this->outputDirectory + "/" + "Web_" + this->outputfile + "/" + "Tiles_" + this->outputfile + "/TileGroup" + tileGroupNumberStr + "";
QDir dir(tilegrouppath);
if (!dir.exists()){
dir.mkpath(".");
}
}
//check if ROI to be cropped is outside of image, if so use image border.
if(((colTile * 256)+tileWidth)>dstImage.cols ){
tileWidth = dstImage.cols - (colTile * 256);
}
if(((rowTile * 256)+tileHeight)>dstImage.rows ){
tileHeight = dstImage.rows - (rowTile * 256);
}
cv::Rect srcTile(colTile * 256,
rowTile * 256,
tileWidth,
tileHeight );
tileInput = dstImage(srcTile);
QString tier_number = QString::number(tierInd);
QString col_number = QString::number(colTile);
QString row_number = QString::number(rowTile);
QString tileGroupNumberStr = QString::number(tileGroupNumber);
QString filepath;
filepath = this->outputDirectory + "/" + "Web_" + this->outputfile + "/" + "Tiles_" + this->outputfile + "/TileGroup" + tileGroupNumberStr + "/" + tier_number + "-" + col_number + "-" + row_number + ".jpg";
try {
imwrite(filepath.toStdString(), tileInput);
}
catch (runtime_error& ex) {
std::cout << "Cannot save: exception convertxing image to correct format:\n" << endl;
return;
}
numberOfTiles++;
}
}
}
void createWeb::copySrcTile(const cv::Mat& src, cv::Mat& srcTile, cv::Rect &tile)
{
//top left corner
auto tl = tile.tl();
//bottom left corner
auto br = tile.br();
cv::Point tloffset, broffset;
//Take care of border cases
if (tile.x < 0)
{
tloffset.x = -tile.x;
tile.x = 0;
}
if (tile.y < 0)
{
tloffset.y = -tile.y;
tile.y = 0;
}
if (br.x >= src.cols)
{
broffset.x = br.x - src.cols + 1;
tile.width -= broffset.x;
}
if (br.y >= src.rows)
{
broffset.y = br.y - src.rows + 1;
tile.height -= broffset.y;
}
// If any of the tile sides exceed source image boundary we must use copyMakeBorder to make proper paddings for this side
if (tloffset.x > 0 || tloffset.y > 0 || broffset.x > 0 || broffset.y > 0)
{
cv::Rect paddedTile(tile.tl(), tile.br());
assert(paddedTile.x >= 0);
assert(paddedTile.y >= 0);
assert(paddedTile.br().x < src.cols);
assert(paddedTile.br().y < src.rows);
cv::copyMakeBorder(src(paddedTile), srcTile, tloffset.y, broffset.y, tloffset.x, broffset.x, BORDER_CONSTANT);
}
else
{
// Entire tile (with paddings lies inside image and it's safe to just take a region:
src(tile).copyTo(srcTile);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment