0% found this document useful (0 votes)
257 views7 pages

Dsa

The document contains C++ code definitions for functions related to image processing and building bounding volume hierarchies (BVHs) for ray tracing. It includes functions to create 1D and 2D Gaussian filter kernels, convolve an image with a filter kernel using separable and non-separable approaches, reorder triangle indices to split a node during BVH construction, and intersect the BVH recursively.

Uploaded by

hans peter
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
257 views7 pages

Dsa

The document contains C++ code definitions for functions related to image processing and building bounding volume hierarchies (BVHs) for ray tracing. It includes functions to create 1D and 2D Gaussian filter kernels, convolve an image with a filter kernel using separable and non-separable approaches, reorder triangle indices to split a node during BVH construction, and intersect the BVH recursively.

Uploaded by

hans peter
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

#include <cglib/rt/bvh.

h>

#include <cglib/rt/triangle_soup.h>

#include <cglib/core/image.h>
#include <complex>

/*
* Create a 1 dimensional normalized gauss kernel
*
* Parameters:
* - sigma: the parameter of the gaussian
* - kernel_size: the size of the kernel (has to be odd)
* - kernel: an array with size kernel_size elements that
* has to be filled with the kernel values
*
*/
void Image::create_gaussian_kernel_1d(
float sigma,
int kernel_size,
float* kernel)
{
cg_assert(kernel_size % 2 == 1);

// TODO: calculate filter values as described on the exercise sheet.


// Make sure your kernel is normalized

int lowestx = -(floor(kernel_size / 2));


float normalize = 0.0;

for (int i = 0; i < kernel_size; ++i) {


kernel[i] = (1.0 / (glm::sqrt(2.0 * glm::pi<float>())* sigma)) *
glm::pow(glm::e<float>(), -((lowestx) * (lowestx) / (2.0* sigma * sigma)));
lowestx++;
}

for (int i = 0; i < kernel_size; ++i) {


normalize += kernel[i];
}
for (int i = 0; i < kernel_size; ++i) {
kernel[i] = kernel[i] / normalize;
}

/*
* Create a 2 dimensional quadratic and normalized gauss kernel
*
* Parameters:
* - sigma: the parameter of the gaussian
* - kernel_size: the size of the kernel (has to be odd)
* - kernel: an array with kernel_size*kernel_size elements that
* has to be filled with the kernel values
*/
void Image::create_gaussian_kernel_2d(
float sigma,
int kernel_size,
float* kernel)
{
cg_assert(kernel_size % 2 == 1);

int lowestnumber = -(floor(kernel_size / 2));


float normalize = 0.0;

for (int j = 0; j < kernel_size; ++j) {

for (int i = 0; i < kernel_size; ++i) {

kernel[i + j * kernel_size] = (1.0 / (2.0 * glm::pi<float>() *


(sigma * sigma)))* glm::pow(glm::e<float>(), -(((lowestnumber + j) * (lowestnumber
+ j) + (lowestnumber + i) * (lowestnumber + i)) / (2.0 * sigma * sigma)));

for (int j = 0; j < kernel_size; ++j) {

for (int i = 0; i < kernel_size; ++i) {


normalize += kernel[i + j*kernel_size];
}
}
for (int j = 0; j < kernel_size; ++j) {

for (int i = 0; i < kernel_size; ++i) {


kernel[i + j * kernel_size] = kernel[i + j*kernel_size] /
normalize;

}
}
}
/*
* Convolve an image with a 2d filter kernel
*
* Parameters:
* - kernel_size: the size of the 2d-kernel
* - kernel: the 2d-kernel with kernel_size*kernel_size elements
* - wrap_mode: needs to be known to handle repeating
* textures correctly
*/
void Image::filter(Image *target, int kernel_size, float* kernel, WrapMode
wrap_mode) const
{
cg_assert(kernel_size % 2 == 1 && "kernel size should be odd.");
cg_assert(kernel_size > 0 && "kernel size should be greater than 0.");
cg_assert(target);
cg_assert(target->getWidth() == m_width && target->getHeight() == m_height);
int lowestnumber = -(floor(kernel_size / 2));
for (int i = 0; i < m_width; ++i) { //rupert hier width statt height
for (int j = 0; j < m_height; ++j) { // height statt width
glm::vec4 newpixel;
for (int a = 0; a < kernel_size; ++a) {
for (int b = 0; b < kernel_size; ++b) {
newpixel += kernel[a + kernel_size*b] * (getPixel(i +
lowestnumber + a, j + lowestnumber + b));
} // a + kernelsize *b nachfragen
}
target->setPixel(i, j, newpixel);
}
}

/*
/*
* Convolve an image with a separable 1d filter kernel
*
* Parameters:
* - kernel_size: the size of the 1d kernel
* - kernel: the 1d-kernel with kernel_size elements
* - wrap_mode: needs to be known to handle repeating
* textures correctly
*/
void Image::filter_separable(Image *target, int kernel_size, float* kernel,
WrapMode wrap_mode) const
{
cg_assert (kernel_size%2==1 && "kernel size should be odd.");
cg_assert (kernel_size > 0 && "kernel size should be greater than 0.");
cg_assert (target);
cg_assert (target->getWidth() == m_width && target->getHeight() == m_height);
Image temp(m_width, m_height);

int lowestnumber = -floor((kernel_size / 2));

for (int i = 0; i < m_width; ++i) {


for (int j = 0; j < m_height; j++) {
glm::vec4 PixelHeight;
for (int k = 0; k < kernel_size; k++) {
PixelHeight += kernel[k] * getPixel(i, j+ lowestnumber + k,
wrap_mode);
} temp.setPixel(i, j, PixelHeight);
}
}

for (int i = 0; i < m_width; ++i) {


for (int j = 0; j < m_height; j++) {
glm::vec4 PixelWidth;
for (int k = 0; k < kernel_size; k++) {
PixelWidth += kernel[k] * temp.getPixel(i+ lowestnumber +
k,j, wrap_mode);
} target->setPixel(i, j, PixelWidth);
}
}
// TODO: realize the 2d convolution with two
// convolutions of the image with a 1d-kernel.
// convolve the image horizontally and then convolve
// the result vertically (or vise-versa).
//
// use the methods getPixel(x, y, wrap_mode) and
// setPixel(x, y, value) to get and set pixels of an image

/**
* Reorder triangle indices in the vector triangle_indices
* in the range [first_triangle_idx, first_triangle_idx+num_triangles-1]
* so that the range is split in two sets where all triangles in the first set
* are "less than equal" than the median, and all triangles in the second set
* are "greater than equal" the median.
*
* Ordering ("less than") is defined by the ordering of triangle
* bounding box centers along the given axis.
*
* Triangle indices within a set need not be sorted.
*
* The resulting sets must have an equal number of elements if num_triangles
* is even. Otherwise, one of the sets must have one more element.
*
* For example, 8 triangles must be split 4-4. 7 Triangles must be split
* 4-3 or 3-4.
*
* Parameters:
* - first_triangle_idx: The index of the first triangle in the given range.
* - num_triangles: The number of triangles in the range.
* - axis: The sort axis. 0 is X, 1 is Y, 2 is Z.
*
* Return value:
* - The number of triangles in the first set.
*/
int BVH::reorder_triangles_median(
int first_triangle_idx,
int num_triangles,
int axis)
{
cg_assert(first_triangle_idx < static_cast<int>(triangle_indices.size()));
cg_assert(first_triangle_idx >= 0);
cg_assert(num_triangles <= static_cast<int>(triangle_indices.size() -
first_triangle_idx));
cg_assert(num_triangles > 1);
cg_assert(axis >= 0);
cg_assert(axis < 3);

// TODO: Implement reordering.


return 0;
}

/*
* Build a BVH recursively using the object median split heuristic.
*
* This method must first fully initialize the current node, and then
* potentially split it.
*
* A node must not be split if it contains MAX_TRIANGLES_IN_LEAF triangles or
* less. No leaf node may be empty. All nodes must have either two or no
* children.
*
* Use reorder_triangles_median to perform the split in triangle_indices.
* Split along X for depth 0. Then, proceed in the order Y, Z, X, Y, Z, X, Y, ..
*
* Parameters:
* - node_idx: The index of the node to be split.
* - first_triangle_idx: An index into the array triangle_indices. It points
* to the first triangle contained in the current node.
* - num_triangles: The number of triangles contained in the current node.
*/
void BVH::
build_bvh(int node_idx, int first_triangle_idx, int num_triangles, int depth)
{
cg_assert(num_triangles > 0);
cg_assert(node_idx >= 0);
cg_assert(node_idx < static_cast<int>(nodes.size()));
cg_assert(depth >= 0);

Node& node = nodes[node_idx];

// TODO: Implement recursive build.


node.triangle_idx = first_triangle_idx;
node.num_triangles = num_triangles;
node.aabb.min = glm::vec3(-FLT_MAX);
node.aabb.max = glm::vec3(FLT_MAX);
node.left = -1;
node.right = -1;
}

/*
* Intersect the BVH recursively, returning the nearest intersection if
* there is one.
*
* Caution: BVH nodes may overlap.
*
* Parameters:
* - ray: The ray to intersect the BVH with.
* - idx: The node to be intersected.
* - nearest_intersection: The distance to the intersection point, if an
* intersection was found. Must not be changed
* otherwise.
* - isect: The intersection, if one was found. Must not be
* changed otherwise.
*
* Return value:
* true if an intersection was found, false otherwise.
*/
bool BVH::
intersect_recursive(const Ray &ray, int idx, float *nearest_intersection,
Intersection* isect) const
{
cg_assert(nearest_intersection);
cg_assert(isect);
cg_assert(idx >= 0);
cg_assert(idx < static_cast<int>(nodes.size()));

const Node &n = nodes[idx];

// This is a leaf node. Intersect all triangles.


if(n.left < 0) {
glm::vec3 bary(0.f);
bool hit = false;
for(int i = 0; i < n.num_triangles; i++) {
int x = triangle_indices[n.triangle_idx + i];
float dist;
glm::vec3 b;
if(intersect_triangle(ray.origin, ray.direction,
triangle_soup.vertices[x * 3 + 0],
triangle_soup.vertices[x * 3 + 1],
triangle_soup.vertices[x * 3 + 2],
b, dist)) {
hit = true;
if(dist <= *nearest_intersection) {
*nearest_intersection = dist;
bary = b;
cg_assert(x >= 0);
if(isect)
triangle_soup.fill_intersection(isect, x,
*nearest_intersection, bary);
}
}
}
return hit;
}

// This is an inner node. Recurse into child nodes.


else {
// TODO: Implement recursive traversal here.
}

return false;
}
// Spectrum and reconstruction are 2D memory blocks of the same size [sx, sy]
// in row major layout, i.e one row of size sx after the other.
//
// Spectrum contains the complex fourier-coefficients \hat{x}_{kl}.
//
// Reconstruct the original grayscale image using fourier transformation!
void DiscreteFourier2D::reconstruct(
int sx, int sy,
std::complex<float> const* spectrum,
std::complex<float> * reconstruction)
{
}
// CG_REVISION 3d6fdd132b9492fa6a480cc37c1514dd9997eedf

You might also like