void FiltMaxImg(const Img& in, const int k_width, const int k_height, const int channel, Img& out) { const int width = in.width(); const int height = in.height(); const int num_channel = in.channel(); assert(num_channel > channel); out.Reshape(width, height, 1); const double* in_data = in.data(); double* out_data = out.mutable_data(); for(int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { int w_start = w - ((k_width) / 2); int h_start = h - ((k_height) / 2); int kw_start = 0; int kh_start = 0; int kw_end = k_width; int kh_end = k_height; double max_value = -MAX_DOUBLE; for (int i = kh_start; i < kh_end; i++ ) { for (int j = kw_start; j < kw_end; j++) { int w_temp = w_start + j; int h_temp = h_start + i; if (w_temp >=0 && w_temp < width && h_temp >= 0 && h_temp < height) { max_value = std::max(max_value, in_data[h_temp * width + w_temp]); } } } out_data[h * width + w] = max_value; } } }
void FiltMedImg(const Img& in, const int k_width, const int k_height, const int channel, Img& out) { const int width = in.width(); const int height = in.height(); const int num_channel = in.channel(); assert(num_channel > channel); out.Reshape(width, height, 1); const double* in_data = in.data(); double* out_data = out.mutable_data(); for(int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { int w_start = w - ((k_width) / 2); int h_start = h - ((k_height) / 2); int kw_start = 0; int kh_start = 0; int kw_end = k_width; int kh_end = k_height; std::vector<double> temp_list; for (int i = kh_start; i < kh_end; i++ ) { for (int j = kw_start; j < kw_end; j++) { int w_temp = w_start + j; int h_temp = h_start + i; if (w_temp >=0 && w_temp < width && h_temp >= 0 && h_temp < height) { temp_list.push_back(in_data[h_temp * width + w_temp]); } } } std::sort(temp_list.begin(), temp_list.end()); out_data[h * width + w] = temp_list[temp_list.size()/2]; } } }
int main() { float scale = 400.f; float offset_x = 5.9f; float offset_y = 5.1f; float offset_z = 0.05f; float lacunarity = 1.99f; float persistance = 0.5f; Img img; while (!img.is_closed()) { Measure measure; measure.start(); const SimplexNoise simplex(0.1f/scale, 0.5f, lacunarity, persistance); // Amplitude of 0.5 for the 1st octave : sum ~1.0f const int octaves = static_cast<int>(5 + std::log(scale)); // Estimate number of octaves needed for the current scale std::ostringstream title; title << "2D Simplex Perlin noise (" << octaves << " octaves)"; img.set_title(title.str().c_str()); for (int row = 0; row < img.height(); ++row) { const float y = static_cast<float>(row - img.height()/2 + offset_y*scale); for (int col = 0; col < img.width(); ++col) { const float x = static_cast<float>(col - img.width()/2 + offset_x*scale); // TODO(SRombauts): Add 'erosion' with simple smoothing like exponential, and other 'modifiers' like in libnoise // Generate "biomes", ie smooth geographic variation in frequency & amplitude, // and add smaller details, summing the noise values for the coordinate const float noise = simplex.fractal(octaves, x, y) + offset_z; const color3f color = ramp(noise); // convert to color img.draw_point(col, row, (float*)&color); } } img.display(); const double diff_ms = measure.get(); std::cout << std::fixed << diff_ms << "ms\n"; img.user(scale, offset_x, offset_y, offset_z, lacunarity, persistance); } return 0; }
void FiltImg(const Img& in, const Img& filter, const int channel, Img& out) { const int width = in.width(); const int height = in.height(); const int num_channel = in.channel(); assert(num_channel > channel); out.Reshape(width, height, 1); const double* in_data = in.data() + channel * out.dim(); const double* filter_data = filter.data(); double* out_data = out.mutable_data(); const int k_width = filter.width(); const int k_height = filter.height(); for(int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { int w_start = w - ((k_width) / 2); int h_start = h - ((k_height) / 2); int kw_start = 0; int kh_start = 0; int kw_end = k_width; int kh_end = k_height; double sum = 0; for (int i = kh_start; i < kh_end; i++ ) { for (int j = kw_start; j < kw_end; j++) { int w_temp = w_start + j; int h_temp = h_start + i; if (w_temp >=0 && w_temp < width && h_temp >= 0 && h_temp < height) { sum += in_data[h_temp * width + w_temp] * filter_data[i * k_width + j]; //printf("%f x %f, ", in_data[h_temp * width + w_temp], filter_data[i * k_width + j]); //printf("%d %d, \n", h_temp, w_temp); } } } out_data[h * width + w] = sum; } } }