diff --git a/Image/Diff.h b/Image/Diff.h new file mode 100644 index 0000000..fc7a4f8 --- /dev/null +++ b/Image/Diff.h @@ -0,0 +1,47 @@ +/** + * Karaka + * + * @package Image + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef IMAGE_DIFF_H +#define IMAGE_DIFF_H + +#include +#include + +#include "../Utils/MathUtils.h" + +namespace Image { + namespace ImageUtils { + cv::Mat find_diff (cv::Mat in1, cv::Mat in2) + { + cv::Mat diff; + cv::absdiff(in1, in2, diff); + + int th = 10; + cv::Mat mask(in1.size(), CV_8UC1); + + for (int i = 0; i < diff.rows; ++i) { + for (int j = 0; j < diff.cols; ++j) { + cv::Vec3b px = diff.at(i, j); + int value = px[0] + px[1] + px[2]; + + if (value > th) { + mask.at(i, j) = 255; + } + } + } + + cv::Mat out; + cv::bitwise_and(in2, in2, out, mask); + + return out; + } + } +} + +#endif \ No newline at end of file diff --git a/Image/ImageUtils.h b/Image/ImageUtils.h index f0e654c..cd1c723 100755 --- a/Image/ImageUtils.h +++ b/Image/ImageUtils.h @@ -14,37 +14,34 @@ #include namespace Image { - class ImageUtils { - private: + namespace ImageUtils { + inline + float lightnessFromRgb(int r, int g, int b) + { + float vR = r / 255.0; + float vG = g / 255.0; + float vB = b / 255.0; - public: - static inline - float lightnessFromRgb(int r, int g, int b) - { - float vR = r / 255.0; - float vG = g / 255.0; - float vB = b / 255.0; + float lR = vR <= 0.04045 ? vR / 12.92 : pow(((vR + 0.055) / 1.055), 2.4); + float lG = vG <= 0.04045 ? vG / 12.92 : pow(((vG + 0.055) / 1.055), 2.4); + float lB = vB <= 0.04045 ? vB / 12.92 : pow(((vB + 0.055) / 1.055), 2.4); - float lR = vR <= 0.04045 ? vR / 12.92 : pow(((vR + 0.055) / 1.055), 2.4); - float lG = vG <= 0.04045 ? vG / 12.92 : pow(((vG + 0.055) / 1.055), 2.4); - float lB = vB <= 0.04045 ? vB / 12.92 : pow(((vB + 0.055) / 1.055), 2.4); + float y = 0.2126 * lR + 0.7152 * lG + 0.0722 * lB; + float lStar = y <= 216.0 / 24389.0 ? y * 24389.0 / 27.0 : pow(y, (1.0 / 3.0)) * 116.0 - 16.0; - float y = 0.2126 * lR + 0.7152 * lG + 0.0722 * lB; - float lStar = y <= 216.0 / 24389.0 ? y * 24389.0 / 27.0 : pow(y, (1.0 / 3.0)) * 116.0 - 16.0; + return lStar / 100.0; + } - return lStar / 100.0; - } + inline + int rgbToInt(int r, int g, int b) + { + int rgb = r; + rgb = (rgb << 8) + g; + rgb = (rgb << 8) + b; - static inline - int rgbToInt(int r, int g, int b) - { - int rgb = r; - rgb = (rgb << 8) + g; - rgb = (rgb << 8) + b; - - return rgb; - } - }; + return rgb; + } + } } #endif \ No newline at end of file diff --git a/Image/Kernel.h b/Image/Kernel.h index 49d5520..d8cb247 100755 --- a/Image/Kernel.h +++ b/Image/Kernel.h @@ -61,23 +61,19 @@ namespace Image { {-1.0 / 256.0, -4.0 / 256.0, -6.0 / 256.0, -4.0 / 256.0, -1.0 / 256.0}, }; - class Kernel { - private: + namespace Kernel { + inline + cv::Mat convolve(cv::Mat in, const float kernel[][3]) + { + cv::Size dim = in.size(); + cv::Mat out(in.size(), in.type()); - public: + cv::Mat mKernel(3, 3, CV_32F, (float *) kernel); + cv::filter2D(in, out, -1, mKernel); - static - cv::Mat convolve(cv::Mat in, const float kernel[][3]) - { - cv::Size dim = in.size(); - cv::Mat out(in.size(), in.type()); - - cv::Mat mKernel(3, 3, CV_32F, (float *) kernel); - cv::filter2D(in, out, -1, mKernel); - - return out; - } - }; + return out; + } + } } #endif \ No newline at end of file diff --git a/Image/Skew.h b/Image/Skew.h index e62c96a..693806f 100755 --- a/Image/Skew.h +++ b/Image/Skew.h @@ -17,79 +17,75 @@ #include "../Utils/MathUtils.h" namespace Image { - class Skew { - private: + namespace Skew { + cv::Mat deskewHoughLines(cv::Mat in, int maxDegree = 45) + { + cv::Size dim = in.size(); - public: - static - cv::Mat deskewHoughLines(cv::Mat in, int maxDegree = 45) - { - cv::Size dim = in.size(); + cv::Mat inv; + cv::cvtColor(in, inv, cv::COLOR_BGR2GRAY); + cv::threshold(inv, inv, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU); - cv::Mat inv; - cv::cvtColor(in, inv, cv::COLOR_BGR2GRAY); - cv::threshold(inv, inv, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU); + std::vector lines; + cv::HoughLinesP(inv, lines, 1.0, OMS_PI / 180, 200, dim.width / 12, dim.width / 150); - std::vector lines; - cv::HoughLinesP(inv, lines, 1.0, OMS_PI / 180, 200, dim.width / 12, dim.width / 150); + int imageOrientation = 0; // > 0 -> image is horizontal - int imageOrientation = 0; // > 0 -> image is horizontal + std::vector tmpAngles; + for (int i = 0; i < lines.size(); ++i) { + float angle = atan2(lines[i][3] - lines[i][1], lines[i][2] - lines[i][0]); + tmpAngles.push_back(angle); - std::vector tmpAngles; - for (int i = 0; i < lines.size(); ++i) { - float angle = atan2(lines[i][3] - lines[i][1], lines[i][2] - lines[i][0]); - tmpAngles.push_back(angle); + imageOrientation += oms_abs(angle) > OMS_PI / 4 ? 1 : -1; + } - imageOrientation += oms_abs(angle) > OMS_PI / 4 ? 1 : -1; - } - - std::vector angles; - for (int i = 0; i < tmpAngles.size(); ++i) { - if (imageOrientation > 0) { - if (oms_deg2rad(90 - maxDegree) < oms_abs(tmpAngles[i]) && oms_abs(tmpAngles[i]) < oms_deg2rad(90 + maxDegree)) { - angles.push_back(tmpAngles[i]); - } - } else { - if (oms_abs(tmpAngles[i]) < oms_deg2rad(maxDegree)) { - angles.push_back(tmpAngles[i]); - } - } - } - - if (angles.size() < 5) { - return in; - } - - float median = 0.0; - for (int i = 0; i < angles.size(); ++i) { - median += angles[i]; - } - - float angleDeg = oms_rad2deg(median / angles.size()); - - cv::Mat orientFix; + std::vector angles; + for (int i = 0; i < tmpAngles.size(); ++i) { if (imageOrientation > 0) { - if (angleDeg < 0) { - cv::rotate(in, orientFix, cv::ROTATE_90_CLOCKWISE); - angleDeg += 90.0; - } else if (angleDeg > 0) { - cv::rotate(in, orientFix, cv::ROTATE_90_COUNTERCLOCKWISE); - angleDeg -= 90.0; - } else { - orientFix = in; + if (oms_deg2rad(90 - maxDegree) < oms_abs(tmpAngles[i]) && oms_abs(tmpAngles[i]) < oms_deg2rad(90 + maxDegree)) { + angles.push_back(tmpAngles[i]); } + } else { + if (oms_abs(tmpAngles[i]) < oms_deg2rad(maxDegree)) { + angles.push_back(tmpAngles[i]); + } + } + } + + if (angles.size() < 5) { + return in; + } + + float median = 0.0; + for (int i = 0; i < angles.size(); ++i) { + median += angles[i]; + } + + float angleDeg = oms_rad2deg(median / angles.size()); + + cv::Mat orientFix; + if (imageOrientation > 0) { + if (angleDeg < 0) { + cv::rotate(in, orientFix, cv::ROTATE_90_CLOCKWISE); + angleDeg += 90.0; + } else if (angleDeg > 0) { + cv::rotate(in, orientFix, cv::ROTATE_90_COUNTERCLOCKWISE); + angleDeg -= 90.0; } else { orientFix = in; } - - cv::Mat rot = cv::getRotationMatrix2D(cv::Point2f(dim.width / 2, dim.height / 2), angleDeg, 1.0); - - cv::Mat out; - cv::warpAffine(orientFix, out, rot, dim, cv::INTER_LINEAR, cv::BORDER_REPLICATE); - - return out; + } else { + orientFix = in; } - }; + + cv::Mat rot = cv::getRotationMatrix2D(cv::Point2f(dim.width / 2, dim.height / 2), angleDeg, 1.0); + + cv::Mat out; + cv::warpAffine(orientFix, out, rot, dim, cv::INTER_LINEAR, cv::BORDER_REPLICATE); + + return out; + } + } } #endif \ No newline at end of file diff --git a/Image/Thresholding.h b/Image/Thresholding.h index 0b9e6f5..e550323 100755 --- a/Image/Thresholding.h +++ b/Image/Thresholding.h @@ -17,67 +17,63 @@ #include "../Utils/MathUtils.h" namespace Image { - class Thresholding { - private: + namespace Thresholding { + cv::Mat integralThresholding(cv::Mat in) + { + cv::Size dim = in.size(); + cv::Mat out(dim, in.type()); - public: - static - cv::Mat integralThresholding(cv::Mat in) - { - cv::Size dim = in.size(); - cv::Mat out(dim, in.type()); + float *intImg = (float *) malloc(dim.width * dim.height * sizeof(float)); + float sum; - float *intImg = (float *) malloc(dim.width * dim.height * sizeof(float)); - float sum; + cv::Vec3b bgr; + for (int i = 0; i < dim.width; ++i) { + sum = 0.0; - cv::Vec3b bgr; - for (int i = 0; i < dim.width; ++i) { - sum = 0.0; + for (int j = 0; j < dim.height; ++j) { + bgr = in.at(j, i); + sum += Image::ImageUtils::lightnessFromRgb(bgr[2], bgr[1], bgr[0]); - for (int j = 0; j < dim.height; ++j) { - bgr = in.at(j, i); - sum += Image::ImageUtils::lightnessFromRgb(bgr[2], bgr[1], bgr[0]); - - intImg[i * j] = i == 0 ? sum : intImg[(i - 1) * j] + sum; - } + intImg[i * j] = i == 0 ? sum : intImg[(i - 1) * j] + sum; } - - int s = dim.width / 96.0; - int t = 30; - - int x1, x2; - int y1, y2; - int count; - float brightness; - int color; - - for (int i = 0; i < dim.width; ++i) { - for (int j = 0; j < dim.height; ++j) { - x1 = oms_max(1, i - s / 2.0); - x2 = oms_min(i + s / 2.0, dim.width - 1); - - y1 = oms_max(1, j - s / 2.0); - y2 = oms_min(j + s / 2.0, dim.height - 1); - - count = (x2 - x1) * (y2 - y1); - sum = intImg[x2 * y2] - intImg[x2 * (y1 - 1)] - intImg[(x1 - 1) * y2] + intImg[(x1 - 1) * (y1 - 1)]; - - bgr = in.at(j, i); - brightness = Image::ImageUtils::lightnessFromRgb(bgr[2], bgr[1], bgr[0]); - - color = brightness * count <= (sum * (100.0 - t) / 100.0) && brightness < 0.95 ? 0 : 255; - - out.at(j, i)[0] = color; - out.at(j, i)[1] = color; - out.at(j, i)[2] = color; - } - } - - free(intImg); - - return out; } - }; + + int s = dim.width / 96.0; + int t = 30; + + int x1, x2; + int y1, y2; + int count; + float brightness; + int color; + + for (int i = 0; i < dim.width; ++i) { + for (int j = 0; j < dim.height; ++j) { + x1 = oms_max(1, i - s / 2.0); + x2 = oms_min(i + s / 2.0, dim.width - 1); + + y1 = oms_max(1, j - s / 2.0); + y2 = oms_min(j + s / 2.0, dim.height - 1); + + count = (x2 - x1) * (y2 - y1); + sum = intImg[x2 * y2] - intImg[x2 * (y1 - 1)] - intImg[(x1 - 1) * y2] + intImg[(x1 - 1) * (y1 - 1)]; + + bgr = in.at(j, i); + brightness = Image::ImageUtils::lightnessFromRgb(bgr[2], bgr[1], bgr[0]); + + color = brightness * count <= (sum * (100.0 - t) / 100.0) && brightness < 0.95 ? 0 : 255; + + out.at(j, i)[0] = color; + out.at(j, i)[1] = color; + out.at(j, i)[2] = color; + } + } + + free(intImg); + + return out; + } + } } #endif \ No newline at end of file diff --git a/Utils/ApplicationUtils.h b/Utils/ApplicationUtils.h index c34acbe..e558915 100755 --- a/Utils/ApplicationUtils.h +++ b/Utils/ApplicationUtils.h @@ -39,6 +39,7 @@ namespace Utils { return cwd; } + inline void chdir_application(char *cwd, char *arg) { #ifdef _WIN32 @@ -80,6 +81,7 @@ namespace Utils { #endif } + inline const char *compile_arg_line(int argc, char **argv) { size_t max = 512; diff --git a/Utils/FileUtils.h b/Utils/FileUtils.h index 63c896e..8294c5b 100755 --- a/Utils/FileUtils.h +++ b/Utils/FileUtils.h @@ -10,6 +10,9 @@ #ifndef UTILS_FILE_UTILS_H #define UTILS_FILE_UTILS_H +#include +#include + #ifdef _WIN32 #include #include @@ -88,6 +91,7 @@ namespace Utils { #endif } + inline const char* file_extension (const char *filename) { char *dot = strrchr((char *) filename, '.'); @@ -104,7 +108,6 @@ namespace Utils { int size; } file_body; - inline file_body read_file (const char *filename) { file_body file = {0}; diff --git a/Utils/WebUtils.h b/Utils/WebUtils.h index 7fcb500..51a949f 100755 --- a/Utils/WebUtils.h +++ b/Utils/WebUtils.h @@ -19,7 +19,6 @@ namespace Utils { namespace WebUtils { - static int write_download_data (void *ptr, size_t size, size_t nmeb, void *stream) { Utils::FileUtils::file_body *out = (Utils::FileUtils::file_body *) stream; @@ -42,7 +41,7 @@ namespace Utils { return out->size; } - static + inline Utils::FileUtils::file_body download (char *url) { Utils::FileUtils::file_body page = {0};