WIP blue_noise impl
This commit is contained in:
parent
b455a469fe
commit
3643dbea1a
3 changed files with 95 additions and 2 deletions
6
Makefile
6
Makefile
|
@ -1,12 +1,14 @@
|
||||||
|
|
||||||
COMMON_FLAGS=-Wall -Wextra -Wpedantic
|
COMMON_FLAGS=-Wall -Wextra -Wpedantic -std=c++17
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
CPPFLAGS=${COMMON_FLAGS} -g -O0
|
CPPFLAGS=${COMMON_FLAGS} -g -O0
|
||||||
else
|
else
|
||||||
CPPFLAGS=${COMMON_FLAGS} -O3 -DNDEBUG
|
CPPFLAGS=${COMMON_FLAGS} -O3 -DNDEBUG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SOURCES=src/main.cpp
|
SOURCES= \
|
||||||
|
src/main.cpp \
|
||||||
|
src/blue_noise.cpp
|
||||||
OBJECTS=${subst .cpp,.o,${SOURCES}}
|
OBJECTS=${subst .cpp,.o,${SOURCES}}
|
||||||
|
|
||||||
all: Dithering
|
all: Dithering
|
||||||
|
|
37
src/blue_noise.cpp
Normal file
37
src/blue_noise.cpp
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#include "blue_noise.hpp"
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
std::vector<bool> dither::blue_noise(std::size_t width, std::size_t height) {
|
||||||
|
std::size_t count = width * height;
|
||||||
|
std::vector<std::size_t> dither_array;
|
||||||
|
dither_array.resize(count);
|
||||||
|
|
||||||
|
std::vector<bool> pbp; // Prototype Binary Pattern
|
||||||
|
pbp.resize(count);
|
||||||
|
|
||||||
|
std::default_random_engine re(std::random_device{}());
|
||||||
|
std::uniform_int_distribution<std::size_t> dist(0, count - 1);
|
||||||
|
|
||||||
|
// initialize pbp
|
||||||
|
for(std::size_t i = 0; i < count; ++i) {
|
||||||
|
if(i < count / 2) {
|
||||||
|
pbp[i] = true;
|
||||||
|
} else {
|
||||||
|
pbp[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// randomize pbp
|
||||||
|
for(std::size_t i = 0; i < count-1; ++i) {
|
||||||
|
decltype(dist)::param_type range{i+1, count-1};
|
||||||
|
std::size_t ridx = dist(re, range);
|
||||||
|
// probably can't use std::swap since using std::vector<bool>
|
||||||
|
bool temp = pbp[i];
|
||||||
|
pbp[i] = pbp[ridx];
|
||||||
|
pbp[ridx] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
54
src/blue_noise.hpp
Normal file
54
src/blue_noise.hpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef BLUE_NOISE_HPP
|
||||||
|
#define BLUE_NOISE_HPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace dither {
|
||||||
|
|
||||||
|
std::vector<bool> blue_noise(std::size_t width, std::size_t height);
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
inline std::size_t twoToOne(std::size_t x, std::size_t y, std::size_t width) {
|
||||||
|
return x + y * width;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::tuple<std::size_t, std::size_t> oneToTwo(std::size_t i, std::size_t width) {
|
||||||
|
return {i % width, i / width};
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr double mu_squared = 1.5 * 1.5;
|
||||||
|
|
||||||
|
inline double gaussian(double x, double y) {
|
||||||
|
return std::exp(-std::sqrt(x*x + y*y)/(2*mu_squared));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double filter(
|
||||||
|
const std::vector<bool>& pbp,
|
||||||
|
std::size_t x, std::size_t y,
|
||||||
|
std::size_t width) {
|
||||||
|
double sum = 0.0;
|
||||||
|
|
||||||
|
// Should be range -M/2 to M/2, but size_t cannot be negative, so range
|
||||||
|
// is 0 to M.
|
||||||
|
// p' = (M + x - (p - M/2)) % M = (3M/2 + x - p) % M
|
||||||
|
// q' = (M + y - (q - M/2)) % M = (3M/2 + y - q) % M
|
||||||
|
for(std::size_t q = 0; q <= width; ++q) {
|
||||||
|
std::size_t q_prime = (3 * width / 2 + y - q) % width;
|
||||||
|
for(std::size_t p = 0; p <= width; ++p) {
|
||||||
|
std::size_t p_prime = (3 * width / 2 + x - p) % width;
|
||||||
|
bool pbp_value = pbp[twoToOne(p_prime, q_prime, width)];
|
||||||
|
if(pbp_value) {
|
||||||
|
sum += gaussian((double)p - width/2.0, (double)q - width/2.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
} // namespace dither::internal
|
||||||
|
|
||||||
|
} // namespace dither
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue