Skip to content

Commit

Permalink
Float based compute
Browse files Browse the repository at this point in the history
  • Loading branch information
dkurt committed Feb 7, 2024
1 parent ce11363 commit 169e309
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 190 deletions.
49 changes: 18 additions & 31 deletions src/mertens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
using namespace cv;
using namespace Halide;

void LaplacianFilter(Mat src, Mat dst, int height, int width) {
void LaplacianFilter(Mat src, Mat dst, int height, int width) {

int8_t filter[3][3] = {{0, -1, 0}, {-1, 4, -1}, {0, -1, 0}};
Buffer<uint8_t> input(src.ptr<uint8_t>(), {width, height});
Buffer<uint8_t> output(dst.ptr<uint8_t>(), {width, height});
Buffer<int8_t> weights(filter);
float filter[3][3] = {{0, -1, 0}, {-1, 4, -1}, {0, -1, 0}};
Buffer<float> input(src.ptr<float>(), {width, height});
Buffer<float> output(dst.ptr<float>(), {width, height});
Buffer<float> weights(filter);

#ifdef __riscv
contrast(input, output);
Expand All @@ -26,11 +26,7 @@ try {

Func input1 = BoundaryConditions::constant_exterior(input, 0);

Expr s = sum(cast<int16_t>(input1(x + r.x, y + r.y)) * weights(r.x + 1, r.y + 1));

Expr sum = clamp(s, 0, 255);

f(x, y) = cast<uint8_t>(sum);
f(x, y) = sum(input1(x + r.x, y + r.y) * weights(r.x + 1, r.y + 1));

f.realize(output);

Expand All @@ -44,9 +40,8 @@ try {
}

void standartDeviation(Mat src, Mat dst, int height, int width) {

Buffer<uint8_t> input(src.ptr<uint8_t>(), {width, height, 3});
Buffer<float> output(dst.ptr<float>(), {width, height});
Buffer<float> input = Buffer<float>::make_interleaved(src.ptr<float>(), width, height, 3);
Buffer<float> output(dst.ptr<float>(), {width, height});
// Buffer<float> result(width, height);

Func f("deviation");
Expand All @@ -55,7 +50,7 @@ void standartDeviation(Mat src, Mat dst, int height, int width) {
try {

Var x("x"), y("y"), c("c");

// step 1 - find mean / sum all bits of r / (1920x1080) / 1920x1080x1

mean(x, y) = cast<float>(input(x, y, 0) + input(x, y, 1) + input(x, y, 2))/3;
Expand All @@ -68,14 +63,7 @@ try {

// step 3 - find square each deviation from the mean / pow(step 2 result, 2) / 1920x1080x3

// step 4-5 - find the sum of squares / 2 1920x1080x1

f(x, y) = (r*r + g*g + b*b)/2;

// step 6 - find the sqrt(variance) / 1920x1080x1

f(x, y) = sqrt(f(x, y));

f(x, y) = sqrt(r*r + g*g + b*b);
// 1 image = 1 result matrix

f.realize(output);
Expand All @@ -90,9 +78,9 @@ try {

void wellExp(Mat src, Mat dst, int height, int width) {

Buffer<uint8_t> input(src.ptr<uint8_t>(), {width, height, 3});
Buffer<float> output(dst.ptr<float>(), {width, height});
Buffer<float> input = Buffer<float>::make_interleaved(src.ptr<float>(), width, height, 3);
Buffer<float> output(dst.ptr<float>(), {width, height});

Func f("well-exposedness");

try {
Expand All @@ -114,7 +102,7 @@ try {
f(x, y) = r * g * b;

// 1 image = 1 result matrix

f.realize(output);
// check sizes + realize()

Expand All @@ -125,10 +113,9 @@ try {

}

void weightsImage(Mat src1, Mat src2, Mat src3, Mat dst, int height, int width) {
Buffer<int8_t> input1(src1.ptr<int8_t>(), {width, height});
Buffer<int8_t> input2(src2.ptr<int8_t>(), {width, height});
Buffer<int8_t> input3(src3.ptr<int8_t>(), {width, height});
void weightsImage(Mat contrast, Mat saturation, Mat wellexp, Mat dst, int height, int width) {
Buffer<float> input1(contrast.ptr<float>(), {width, height});
Buffer<float> input2(saturation.ptr<float>(), {width, height});
Buffer<float> output(dst.ptr<float>(), {width, height});

Func f("weights");
Expand All @@ -137,7 +124,7 @@ try {

Var x("x"), y("y"), c("c");

f(x, y) = input1(x, y) * input2(x, y) * input3(x, y) + 1e-12f;
f(x, y) = input1(x, y) * input2(x, y) + 1e-12f;

// 3 params = 1 weights matrix

Expand Down
151 changes: 151 additions & 0 deletions test/test_hdr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#include <opencv2/ts.hpp>

#include "algos.hpp"

using namespace cv;

TEST(hdr, halide) {

Mat image1 = imread("1.jpg");
Mat image2 = imread("2.jpg");
Mat image3 = imread("3.jpg");
Mat image4 = imread("4.jpg");

image1.convertTo(image1, CV_32F, 1.0f/255.0f);
image2.convertTo(image2, CV_32F, 1.0f/255.0f);
image3.convertTo(image3, CV_32F, 1.0f/255.0f);
image4.convertTo(image4, CV_32F, 1.0f/255.0f);

Mat image1Gray;
Mat image2Gray;
Mat image3Gray;
Mat image4Gray;
cvtColor(image1, image1Gray, cv::COLOR_BGR2GRAY);
cvtColor(image2, image2Gray, cv::COLOR_BGR2GRAY);
cvtColor(image3, image3Gray, cv::COLOR_BGR2GRAY);
cvtColor(image4, image4Gray, cv::COLOR_BGR2GRAY);

int imageWidth = image1Gray.cols;
int imageHeigth = image1Gray.rows;

int size = imageHeigth * imageHeigth;

Mat laplaced1(imageHeigth, imageWidth, CV_32F);
Mat laplaced2(imageHeigth, imageWidth, CV_32F);
Mat laplaced3(imageHeigth, imageWidth, CV_32F);
Mat laplaced4(imageHeigth, imageWidth, CV_32F);

LaplacianFilter(image1Gray, laplaced1, imageHeigth, imageWidth); // LaplacianFilter - 1920x1080x1 as result
LaplacianFilter(image2Gray, laplaced2, imageHeigth, imageWidth);
LaplacianFilter(image3Gray, laplaced3, imageHeigth, imageWidth);
LaplacianFilter(image4Gray, laplaced4, imageHeigth, imageWidth);

laplaced1 = abs(laplaced1); //absolute value
laplaced2 = abs(laplaced2);
laplaced3 = abs(laplaced3);
laplaced4 = abs(laplaced4);

imwrite("laplaced1.jpg", laplaced1 * 255); //write laplaced images
imwrite("laplaced2.jpg", laplaced2 * 255);
imwrite("laplaced3.jpg", laplaced3 * 255);
imwrite("laplaced4.jpg", laplaced4 * 255);

std::cout << "check LaplacedFilter" << std::endl;

Mat stDev1(imageHeigth, imageWidth, CV_32F);
Mat stDev2(imageHeigth, imageWidth, CV_32F);
Mat stDev3(imageHeigth, imageWidth, CV_32F);
Mat stDev4(imageHeigth, imageWidth, CV_32F);

//check stability of image1/2/3/4

standartDeviation(image1, stDev1, imageHeigth, imageWidth); // Calculation of standrat deviation - 1920x1080x1 as result
standartDeviation(image2, stDev2, imageHeigth, imageWidth);
standartDeviation(image3, stDev3, imageHeigth, imageWidth);
standartDeviation(image4, stDev4, imageHeigth, imageWidth);

std::cout << "check standartDeviation" << std::endl;

Mat we1(imageHeigth, imageWidth, CV_32F);
Mat we2(imageHeigth, imageWidth, CV_32F);
Mat we3(imageHeigth, imageWidth, CV_32F);
Mat we4(imageHeigth, imageWidth, CV_32F);

wellExp(image1, we1, imageHeigth, imageWidth); // Calculation of well-exposedness - 1920x1080x1 as result
wellExp(image2, we2, imageHeigth, imageWidth);
wellExp(image3, we3, imageHeigth, imageWidth);
wellExp(image4, we4, imageHeigth, imageWidth);

std::cout << "check well-exposedness" << std::endl;

Mat weights1(imageHeigth, imageWidth, CV_32F);
Mat weights2(imageHeigth, imageWidth, CV_32F);
Mat weights3(imageHeigth, imageWidth, CV_32F);
Mat weights4(imageHeigth, imageWidth, CV_32F);

//pow() ??????

weightsImage(laplaced1, stDev1, we1, weights1, imageHeigth, imageWidth); // Calculation of weight map - 1920x1080x1 as result
weightsImage(laplaced2, stDev2, we2, weights2, imageHeigth, imageWidth);
weightsImage(laplaced3, stDev3, we3, weights3, imageHeigth, imageWidth);
weightsImage(laplaced4, stDev4, we4, weights4, imageHeigth, imageWidth);

std::vector<Mat> weightsVec = {weights1, weights2, weights3, weights4};

std::vector<Mat> imagesVec = {image1, image2, image3, image4};

std::cout << "check weights" << std::endl;

Mat weights_sum(imageHeigth, imageWidth, CV_32F);

weight_sum(weights1, weights2, weights3, weights4, weights_sum, imageHeigth, imageWidth);

std::cout << "check weights sum" << std::endl;

//opencv code

int maxlevel = static_cast<int>(logf(static_cast<float>(min(imageWidth, imageHeigth))) / logf(2.0f));
std::vector<Mat> res_pyr(maxlevel + 1);
std::vector<Mutex> res_pyr_mutexes(maxlevel + 1);

parallel_for_(Range(0, static_cast<int>(imagesVec.size())), [&](const Range& range) {
for(int i = range.start; i < range.end; i++) {
weightsVec[i] /= weights_sum;

std::vector<Mat> img_pyr, weight_pyr;
buildPyramid(imagesVec[i], img_pyr, maxlevel);
buildPyramid(weightsVec[i], weight_pyr, maxlevel);

for(int lvl = 0; lvl < maxlevel; lvl++) {
Mat up;
pyrUp(img_pyr[lvl + 1], up, img_pyr[lvl].size());
img_pyr[lvl] -= up;
}
for(int lvl = 0; lvl <= maxlevel; lvl++) {
std::vector<Mat> splitted(3);
split(img_pyr[lvl], splitted);
for(int c = 0; c < 3; c++) {
splitted[c] = splitted[c].mul(weight_pyr[lvl]);
}
merge(splitted, img_pyr[lvl]);

AutoLock lock(res_pyr_mutexes[lvl]);
if(res_pyr[lvl].empty()) {
res_pyr[lvl] = img_pyr[lvl];
} else {
res_pyr[lvl] += img_pyr[lvl];
}
}
}
});
for(int lvl = maxlevel; lvl > 0; lvl--) {
Mat up;
pyrUp(res_pyr[lvl], up, res_pyr[lvl - 1].size());
res_pyr[lvl - 1] += up;
}

Mat dst = res_pyr[0];

imwrite("FinalImage.jpg", dst * 255);

}
Loading

0 comments on commit 169e309

Please sign in to comment.