From 0d7b5ec5a0f7d3e8c9823c2dfda0f79a60cd20bf Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 14 Aug 2022 20:25:49 +0200 Subject: [PATCH] add rgbtoint --- Image/ImageUtils.h | 10 ++++ Image/Kernel.h | 117 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 Image/Kernel.h diff --git a/Image/ImageUtils.h b/Image/ImageUtils.h index 7f78a74..f0e654c 100644 --- a/Image/ImageUtils.h +++ b/Image/ImageUtils.h @@ -34,6 +34,16 @@ namespace Image { return lStar / 100.0; } + + static inline + int rgbToInt(int r, int g, int b) + { + int rgb = r; + rgb = (rgb << 8) + g; + rgb = (rgb << 8) + b; + + return rgb; + } }; } diff --git a/Image/Kernel.h b/Image/Kernel.h new file mode 100644 index 0000000..c31576c --- /dev/null +++ b/Image/Kernel.h @@ -0,0 +1,117 @@ +/** + * Karaka + * + * @package Image + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef IMAGE_KERNEL_H +#define IMAGE_KERNEL_H + +#include +#include + +#include "ImageUtils.h" +#include "../Utils/MathUtils.h" + +namespace Image { + const float KERNEL_RIDGE_1[3][3] = { + {0.0, -1.0, 0.0}, + {-1.0, 4.0, -1.0}, + {0.0, -1.0, 0.0} + }; + + const float KERNEL_RIDGE_2[3][3] = { + {-1.0, -1.0, -1.0}, + {-1.0, 8.0, -1.0}, + {-1.0, -1.0, -1.0} + }; + + const float KERNEL_SHARPEN[3][3] = { + {0.0, -1.0, 0.0}, + {-1.0, 5.0, -1.0}, + {0.0, -1.0, 0.0} + }; + + const float KERNEL_BOX_BLUR[3][3] = { + {1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0}, + {1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0}, + {1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0} + }; + + const float KERNEL_GAUSSUAN_BLUR_3[3][3] = { + {1.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0}, + {2.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0}, + {1.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0} + }; + + const float KERNEL_EMBOSS[3][3] = { + {-2.0, -1.0, 0.0}, + {-1.0, 1.0, 1.0}, + {0.0, 1.0, 2.0} + }; + + const float KERNEL_UNSHARP_MASKING[5][5] = { + {-1.0 / 256.0, -4.0 / 256.0, -6.0 / 256.0, -4.0 / 256.0, -1.0 / 256.0}, + {-4.0 / 256.0, -16.0 / 256.0, -24.0 / 256.0, -16.0 / 256.0, -4.0 / 256.0}, + {-6.0 / 256.0, -24.0 / 256.0, 476.0 / 256.0, -24.0 / 256.0, -6.0 / 256.0}, + {-4.0 / 256.0, -16.0 / 256.0, -24.0 / 256.0, -16.0 / 256.0, -4.0 / 256.0}, + {-1.0 / 256.0, -4.0 / 256.0, -6.0 / 256.0, -4.0 / 256.0, -1.0 / 256.0}, + }; + + class Kernel { + private: + + public: + + /** + * @see https://en.wikipedia.org/wiki/Kernel_(image_processing) + * @see https://towardsdatascience.com/image-processing-with-python-blurring-and-sharpening-for-beginners-3bcebec0583a + * @see https://web.eecs.umich.edu/~jjcorso/t/598F14/files/lecture_0924_filtering.pdf + */ + static + cv::Mat convolve(cv::Mat in, const float kernel[][3]) + { + cv::Size dim = in.size(); + cv::Mat out(in.size(), in.type()); + + int kernel_dimension = 3; + + int kWidthRadius = (unsigned int) kernel_dimension >> 1; + int kHeightRadius = (unsigned int) kernel_dimension >> 1; + + int newPixel; + cv::Vec3b p; + + // @todo: implement @see https://rosettacode.org/wiki/Image_convolution + // @todo: not working yet + for (int i = dim.width - 1; i >= 0; --i) { + for (int j = dim.height - 1; j >= 0; --j) { + newPixel = 0; + + for (int ki = kernel_dimension - 1; ki >= 0; --ki) { + for (int kj = kernel_dimension - 1; kj >= 0; --kj) { + p = in.at( + oms_min(oms_max(j + kj - kHeightRadius, 0), dim.height - 1), + oms_min(oms_max(i + ki - kWidthRadius, 0), dim.width - 1) + ); + + newPixel += kernel[ki][kj] * Image::ImageUtils::rgbToInt(p[2], p[1], p[0]); + } + } + + // bgr vs rgb + out.at(j, i)[0] = newPixel & 255; + out.at(j, i)[1] = (newPixel >> 8) & 255; + out.at(j, i)[2] = (newPixel >> 16) & 255; + } + } + + return out; + } + }; +} + +#endif \ No newline at end of file