Skip to content

Commit

Permalink
Add preliminar version of integral image
Browse files Browse the repository at this point in the history
  • Loading branch information
arrufat committed Apr 25, 2024
1 parent 149bed1 commit 522c5aa
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/image.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ const std = @import("std");
const Allocator = std.mem.Allocator;
const Rgba = @import("color.zig").Rgba;
const as = @import("meta.zig").as;
const isScalar = @import("meta.zig").isScalar;
const isStruct = @import("meta.zig").isStruct;
const Rectangle = @import("geometry.zig").Rectangle(f32);
const Point2d = @import("point.zig").Point2d(f32);

Expand Down Expand Up @@ -152,5 +154,50 @@ pub fn Image(comptime T: type) type {
}
return chip;
}

pub fn computeIntegralImage(self: Self, allocator: Allocator) if (isScalar(T)) Image(f32) else if (isStruct(T)) Image([std.meta.fields(T).len]f32) else @compileError("Can't compute the integral image of " ++ @typeName(T) ++ ".") {
switch (@typeInfo(T)) {
.ComptimeInt, .Int, .ComptimeFloat, .Float => {
var integral = Image(f32).initAlloc(allocator, self.rows, self.cols);
var tmp: f32 = 0;
for (0..self.cols) |c| {
tmp += as(f32, (self.data[c]));
integral.data[c] = tmp;
}
for (1..self.rows) |r| {
tmp = 0;
for (0..self.cols) |c| {
const curr_pos = r * self.cols + c;
const prev_pos = (r - 1) * self.cols + c;
tmp += as(f32, self.data[curr_pos]);
integral.data[curr_pos] = tmp + integral.data[prev_pos];
}
}
return integral;
},
.Struct => {
const num_fields = std.meta.fields(T).len;
var integral = Image([num_fields]f32).initAlloc(self.rows, self.cols);
inline for (std.meta.fields(T), 0..) |f, i| {
var tmp: f32 = 0;
for (0..self.cols) |c| {
tmp[i] += as(f32, @field(self, f.name));
integral.data[c][i] = tmp[i];
}
for (1..self.rows) |r| {
tmp = 0;
for (0..self.cols) |c| {
const curr_pos = r * self.cols + c;
const prev_pos = (r - 1) * self.cols + c;
tmp += as(f32, self.data[curr_pos][i]);
integral.data[curr_pos][i] = tmp + integral.data[prev_pos][i];
}
}
}
return integral;
},
else => @compileError("Can't compute the integral image of " ++ @typeName(T) ++ "."),
}
}
};
}
16 changes: 16 additions & 0 deletions src/meta.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,19 @@ pub inline fn as(comptime T: type, from: anytype) T {
else => @compileError(@typeName(@TypeOf(from) ++ " is not supported.")),
}
}

/// Returns true if and only if T represents a scalar type.
pub inline fn isScalar(comptime T: type) bool {
return switch (@typeInfo(T)) {
.ComptimeInt, .Int, .ComptimeFloat, .Float => true,
else => false,
};
}

/// Returns true if and only if T represents a struct type.
pub inline fn isStruct(comptime T: type) bool {
return switch (@typeInfo(T)) {
.Struct => true,
else => false,
};
}

0 comments on commit 522c5aa

Please sign in to comment.