Skip to content

Commit

Permalink
Merge pull request #13 from dipsywong98/daniel
Browse files Browse the repository at this point in the history
Fixed mosaic bug
  • Loading branch information
danvim authored Feb 25, 2019
2 parents f0bafc0 + 4e09d2a commit 61df25a
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 14 deletions.
74 changes: 74 additions & 0 deletions ImageUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,80 @@ void ImageUtils::pasteImage(T* sourceImgDataPtr, const Dim& sourceDim, long star
}
}

template <typename T>
std::pair<T*, Dim> ImageUtils::maxPool(T* sourceImgDataPtr, const Dim& sourceDim, const long poolSize)
{
Dim targetDim = { sourceDim.width/poolSize, sourceDim.height/poolSize };
Dim poolDim = { poolSize, poolSize };

T* t = new T[targetDim.getLength()];

for (auto y = 0; y < targetDim.height; y++)
{
for (auto x = 0; x < targetDim.width; x++)
{
T* clip = subImage(sourceImgDataPtr, sourceDim, x * poolSize, y * poolSize, poolDim);
T* tPixel = getPixelPtr(t, targetDim, x, y);

auto max = 0.0;

eachPixel<T>(clip, poolDim, [&](T* rgbArray, long, long)
{
auto sum = rgbArray[0] + rgbArray[1] + rgbArray[2];
if (sum > max)
{
max = sum;
tPixel[0] = rgbArray[0];
tPixel[1] = rgbArray[1];
tPixel[2] = rgbArray[2];
}
});

delete[] clip;
}
}

return { t, targetDim };
}

template <typename T>
std::pair<T*, Dim> ImageUtils::meanPool(T* sourceImgDataPtr, const Dim& sourceDim, const long poolSize)
{
Dim targetDim = { sourceDim.width / poolSize, sourceDim.height / poolSize };
Dim poolDim = { poolSize, poolSize };
const double numPoolPixels = poolDim.width * poolDim.height;

T* t = new T[targetDim.getLength()];

for (auto y = 0; y < targetDim.height; y++)
{
for (auto x = 0; x < targetDim.width; x++)
{
T* clip = subImage(sourceImgDataPtr, sourceDim, x * poolSize, y * poolSize, poolDim);
T* tPixel = getPixelPtr(t, targetDim, x, y);

double rSum = 0;
double gSum = 0;
double bSum = 0;

eachPixel<T>(clip, poolDim, [&](T* rgbArray, long, long)
{
rSum += rgbArray[0];
gSum += rgbArray[1];
bSum += rgbArray[2];
});

tPixel[0] = static_cast<T>(rSum / numPoolPixels);
tPixel[1] = static_cast<T>(gSum / numPoolPixels);
tPixel[2] = static_cast<T>(bSum / numPoolPixels);

delete[] clip;
}
}

return { t, targetDim };
}

template <typename T, typename U>
U* ImageUtils::toNewType(T* fromImgDataPtr, const Dim& dim)
{
Expand Down
36 changes: 36 additions & 0 deletions ImageUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,24 @@ class ImageUtils
template <typename T>
static T* subImage(T* sourceImgDataPtr, const Dim& sourceDim, long startX, long startY, const Dim& targetDim);

/**
*
* @tparam T type of image data array.
* @param sourceImgDataPtr pointer to the source image data array.
* @param sourceDim dimension of the source image.
* @param startX x-location of the top left coordinate of the source of the sub image in the source image.
* @param startY y-location of the top left coordinate of the source of the sub image in the source image.
* @param pasteImgDataPtr pointer to the smaller image data array.
* @param pasteDim dimension of the smaller image.
*/
template <typename T>
static void pasteImage(T* sourceImgDataPtr, const Dim& sourceDim, long startX, long startY, T* pasteImgDataPtr, const Dim& pasteDim);

template <typename T>
static std::pair<T*, Dim> maxPool(T* sourceImgDataPtr, const Dim& sourceDim, long poolSize);

template <typename T>
static std::pair<T*, Dim> meanPool(T* sourceImgDataPtr, const Dim& sourceDim, long poolSize);
};

//Template prototype functions
Expand All @@ -166,6 +182,10 @@ template unsigned char* ImageUtils::subImage(unsigned char*, const Dim&, long, l
template double* ImageUtils::subImage(double*, const Dim&, long, long, const Dim&);
template void ImageUtils::pasteImage(unsigned char*, const Dim&, long, long, unsigned char*, const Dim&);
template void ImageUtils::pasteImage(double*, const Dim&, long, long, double*, const Dim&);
template std::pair<double*, Dim> ImageUtils::maxPool(double* sourceImgDataPtr, const Dim& sourceDim, long poolSize);
template std::pair<unsigned char*, Dim> ImageUtils::maxPool(unsigned char* sourceImgDataPtr, const Dim& sourceDim, long poolSize);
template std::pair<double*, Dim> ImageUtils::meanPool(double* sourceImgDataPtr, const Dim& sourceDim, long poolSize);
template std::pair<unsigned char*, Dim> ImageUtils::meanPool(unsigned char* sourceImgDataPtr, const Dim& sourceDim, long poolSize);

template <typename T>
struct ImageWrapper
Expand Down Expand Up @@ -227,6 +247,22 @@ struct ImageWrapper
{
ImageUtils::pasteImage(dataPtr, dim, x, y, other.dataPtr, other.dim);
}
ImageWrapper maxPool(long poolSize)
{
auto[pooledImage, pooledDim] = ImageUtils::maxPool(dataPtr, dim, poolSize);
return {
pooledImage,
pooledDim
};
}
ImageWrapper meanPool(long poolSize)
{
auto[pooledImage, pooledDim] = ImageUtils::meanPool(dataPtr, dim, poolSize);
return {
pooledImage,
pooledDim
};
}
ImageWrapper(T* imgDataPtr, const Dim& dim): dataPtr(imgDataPtr), dim(dim) {}
ImageWrapper(const ImageWrapper& other)
{
Expand Down
29 changes: 18 additions & 11 deletions MosaicBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ ImageWrapper<unsigned char> MosaicBuilder::makeGradientImage(const ImageWrapper<
rgbArray[2] = 255;
});

return sobelY;
auto gradient = sobelY.maxPool(5);

return gradient;
}

ImageWrapper<unsigned char> MosaicBuilder::makeColorImage(const ImageWrapper<unsigned char>& imgWrapper)
Expand Down Expand Up @@ -175,8 +177,9 @@ ImageWrapper<unsigned char> MosaicBuilder::makeColorImage(const ImageWrapper<uns
auto colorImg = imgWrapper;

colorImg.convolve(gaussianKernel, kernelSize);
auto meanColor = colorImg.meanPool(6);

return colorImg;
return meanColor;
}

bool MosaicBuilder::loadAllTiles()
Expand All @@ -203,21 +206,21 @@ bool MosaicBuilder::loadAllTiles()
if (imagePool.count(name) == 0)
{
//Load and add images to pool.
int width;
int height;
auto width = 0;
auto height = 0;

imagePool[name] = ImageSet{
new ImageWrapper<unsigned char>{
readBMP(entry.path().string().c_str(), width, height),
TILE_DIM
{ width, height }
},
new ImageWrapper<unsigned char>{
readBMP(entry.path().string().c_str(), width, height),
TILE_DIM
readBMP(resultGradientPath.string().c_str(), width, height),
{ width, height }
},
new ImageWrapper<unsigned char>{
readBMP(entry.path().string().c_str(), width, height),
TILE_DIM
readBMP(resultColorPath.string().c_str(), width, height),
{ width, height }
}
};
}
Expand Down Expand Up @@ -264,7 +267,9 @@ void MosaicBuilder::saveGradientImage(ImageWrapper<unsigned char>& imgWrapper, c
imgWrapper.dataPtr = readBMP(imgPath.string().c_str(), width, height);
}

writeBMP(resultGradientPath.string().c_str(), TILE_DIM.width, TILE_DIM.height, makeGradientImage(imgWrapper).dataPtr);
const auto gradient = makeGradientImage(imgWrapper);

writeBMP(resultGradientPath.string().c_str(), gradient.dim.width, gradient.dim.height, gradient.dataPtr);
}
}

Expand All @@ -282,6 +287,8 @@ void MosaicBuilder::saveColorImage(ImageWrapper<unsigned char>& imgWrapper, cons
imgWrapper.dataPtr = readBMP(imgPath.string().c_str(), width, height);
}

writeBMP(resultColorPath.string().c_str(), TILE_DIM.width, TILE_DIM.height, makeColorImage(imgWrapper).dataPtr);
const auto color = makeColorImage(imgWrapper);

writeBMP(resultColorPath.string().c_str(), color.dim.width, color.dim.height, color.dataPtr);
}
}
6 changes: 3 additions & 3 deletions MosaicImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ void MosaicImage::applySubstitutions()

auto limit = static_cast<int>(MosaicBuilder::tileLimitSliderPtr->value());

for (auto& pair : MosaicBuilder::imagePool)
for (auto& [key, set] : MosaicBuilder::imagePool)
{
if (limit == 0) break;
const auto score = MosaicBuilder::calculateScores(sourceTile, pair.second);
const auto score = MosaicBuilder::calculateScores(sourceTile, set);
if (score < bestScore)
{
bestScore = score;
bestImagePtr = pair.second.original;
bestImagePtr = set.original;
}
limit--;
}
Expand Down

0 comments on commit 61df25a

Please sign in to comment.