Making mosaic images with ffmpeg
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
1.4 KiB

#include "rgb.hpp"
#include "math.hpp"
#include <image_io.hpp>
#include <av/sws.hpp>
#include <algorithm>
#include <iostream>
namespace fingerprints {
static raw_rgb_image downscale_step(av::frame const & frame, int factor) {
raw_rgb_image image(frame->width / factor, frame->height / factor);
auto context = sws::create_context(frame, image.frame);
sws::scale(context, frame, image.frame);
return image;
}
static raw_rgb_image downscale_to(av::frame const & frame, int w, int h){
// ffmpeg doesnt let us downscale all the way to 5 at once :(, so we do a loop
raw_rgb_image image;
auto* new_frame = &frame;
while((*new_frame)->width > 8*w && (*new_frame)->height > 8*h){
image = downscale_step(*new_frame, 4);
new_frame = &image.frame;
}
return to_raw_rgb_image(image.frame, w, h);
}
rgb rgb::pre_calculate(av::frame const & frame){
auto const image = downscale_to(crop_to_square(frame), 5, 5);
rgb ret;
ret.data.assign(image.data.size(), 0);
std::copy(image.data.begin(), image.data.end(), ret.data.begin());
return ret;
}
rgb rgb::calculate(const av::frame& frame){
return pre_calculate(frame);
}
double rgb::distance_to(const rgb& fingerprint) const {
assert(data.size() == fingerprint.data.size());
double distance = 0;
for(size_t i = 0; i < data.size(); ++i){
distance += square(data[i] - fingerprint.data[i]);
}
return distance;
}
} // namespace fingerprints