Fixed downscaling metric
This commit is contained in:
parent
224b7bfc0b
commit
dd6e1abb49
4 changed files with 44 additions and 10 deletions
|
@ -1,11 +1,39 @@
|
||||||
#include "downscale.hpp"
|
#include "downscale.hpp"
|
||||||
|
|
||||||
#include <image_io.hpp>
|
#include <image_io.hpp>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
downscale downscale::pre_calculate(const av::frame& frame){
|
extern "C" {
|
||||||
// ffmpeg doesnt let us downscale all the way to 5 at once :(
|
#include <libavutil/frame.h>
|
||||||
auto const image = to_raw_rgb_image(frame, 5, 5);
|
#include <libswscale/swscale.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
static raw_rgb_image downscale_step(AVFrame const * frame, int factor) {
|
||||||
|
raw_rgb_image image(frame->width / factor, frame->height / factor);
|
||||||
|
|
||||||
|
auto context = sws_getContext(frame->width, frame->height, static_cast<AVPixelFormat>(frame->format), image.width(), image.height(), image.format(), 0, nullptr, nullptr, nullptr);
|
||||||
|
if(!context) throw std::runtime_error("boem sws context");
|
||||||
|
sws_scale (context, {frame->data}, {frame->linesize}, 0, frame->height, {image.frame->data}, {image.frame->linesize});
|
||||||
|
sws_freeContext(context);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
static raw_rgb_image downscale_to(const av::frame &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.get();
|
||||||
|
while(new_frame->width > 8*w && new_frame->height > 8*h){
|
||||||
|
image = downscale_step(new_frame, 4);
|
||||||
|
new_frame = image.frame.get();
|
||||||
|
}
|
||||||
|
return to_raw_rgb_image(image.frame, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
downscale downscale::pre_calculate(av::frame const & frame){
|
||||||
|
auto const image = downscale_to(crop_to_square(frame), 5, 5);
|
||||||
|
|
||||||
downscale ret;
|
downscale ret;
|
||||||
ret.data.assign(image.data.size(), 0);
|
ret.data.assign(image.data.size(), 0);
|
||||||
|
@ -19,7 +47,7 @@ downscale downscale::calculate(const av::frame& frame){
|
||||||
return pre_calculate(frame);
|
return pre_calculate(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
double square(double x){
|
static double square(double x){
|
||||||
return x*x;
|
return x*x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,11 @@ extern "C" {
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
|
||||||
|
raw_rgb_image::raw_rgb_image()
|
||||||
|
: data()
|
||||||
|
, frame(nullptr, [](auto x){ av_frame_free(&x); })
|
||||||
|
{}
|
||||||
|
|
||||||
raw_rgb_image::raw_rgb_image(int W, int H)
|
raw_rgb_image::raw_rgb_image(int W, int H)
|
||||||
: data(make_u(avpicture_get_size(AV_PIX_FMT_RGB24, W, H)))
|
: data(make_u(avpicture_get_size(AV_PIX_FMT_RGB24, W, H)))
|
||||||
, frame(av::frame_alloc())
|
, frame(av::frame_alloc())
|
||||||
|
|
|
@ -13,6 +13,7 @@ struct raw_rgb_image {
|
||||||
std::vector<uint8_t, av::allocator<uint8_t>> data;
|
std::vector<uint8_t, av::allocator<uint8_t>> data;
|
||||||
av::frame frame;
|
av::frame frame;
|
||||||
|
|
||||||
|
raw_rgb_image();
|
||||||
raw_rgb_image(int W, int H);
|
raw_rgb_image(int W, int H);
|
||||||
|
|
||||||
int width() const;
|
int width() const;
|
||||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -28,10 +28,10 @@ using namespace std;
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
namespace ar = boost::archive;
|
namespace ar = boost::archive;
|
||||||
|
|
||||||
using Database = image_database<rgb_wavelet_coefficients>;
|
using Database = image_database<downscale>;
|
||||||
using Mozaic = map<pair<int, int>, string>;
|
using Mozaic = map<pair<int, int>, string>;
|
||||||
|
|
||||||
Database read_database(string const & database_directory){
|
static Database read_database(string const & database_directory){
|
||||||
Database db;
|
Database db;
|
||||||
auto const database_file = database_directory + ".db";
|
auto const database_file = database_directory + ".db";
|
||||||
|
|
||||||
|
@ -60,10 +60,10 @@ Database read_database(string const & database_directory){
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mozaic create_mozaic(Database const & db, string const & filename, int h_tiles, int v_tiles){
|
static Mozaic create_mozaic(Database const & db, string const & filename, int h_tiles, int v_tiles){
|
||||||
Mozaic mozaic;
|
Mozaic mozaic;
|
||||||
|
|
||||||
apply_to_tiles("image.jpg", h_tiles, v_tiles, [&](int c, int r, av::frame const & frame){
|
apply_to_tiles(filename, h_tiles, v_tiles, [&](int c, int r, av::frame const & frame){
|
||||||
auto const index = db.nearest_image(frame);
|
auto const index = db.nearest_image(frame);
|
||||||
cout << colors::red("tile ") << c << ", " << r << ": " << db.filename(index) << endl;
|
cout << colors::red("tile ") << c << ", " << r << ": " << db.filename(index) << endl;
|
||||||
mozaic[make_pair(c, r)] = db.filename(index);
|
mozaic[make_pair(c, r)] = db.filename(index);
|
||||||
|
@ -72,7 +72,7 @@ Mozaic create_mozaic(Database const & db, string const & filename, int h_tiles,
|
||||||
return mozaic;
|
return mozaic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_mozaic(Mozaic const & mozaic, string filename, int h_tiles, int v_tiles){
|
static void save_mozaic(Mozaic const & mozaic, string filename, int h_tiles, int v_tiles){
|
||||||
auto const pix_fmt = AV_PIX_FMT_YUVJ444P;
|
auto const pix_fmt = AV_PIX_FMT_YUVJ444P;
|
||||||
auto const codec_id= AV_CODEC_ID_MJPEG;
|
auto const codec_id= AV_CODEC_ID_MJPEG;
|
||||||
|
|
||||||
|
|
Reference in a new issue