|
|
@ -1,7 +1,7 @@ |
|
|
|
#include <image_io.hpp> |
|
|
|
#include <wavelet.hpp> |
|
|
|
#include <image_database.hpp> |
|
|
|
#include <fingerprint.hpp> |
|
|
|
#include <fingerprints.hpp> |
|
|
|
|
|
|
|
#include <boost/filesystem.hpp> |
|
|
|
#include <boost/archive/binary_oarchive.hpp> |
|
|
@ -21,6 +21,9 @@ extern "C" { |
|
|
|
#include <map> |
|
|
|
#include <set> |
|
|
|
|
|
|
|
static const int tile_width = 128; |
|
|
|
static const int tile_height = 128; |
|
|
|
|
|
|
|
using namespace std; |
|
|
|
namespace fs = boost::filesystem; |
|
|
|
namespace ar = boost::archive; |
|
|
@ -29,15 +32,15 @@ using Database = image_database<rgb_wavelet_coefficients>; |
|
|
|
using Mozaic = map<pair<int, int>, string>; |
|
|
|
|
|
|
|
Database read_database(string const & database_directory){ |
|
|
|
image_database<rgb_wavelet_coefficients> db; |
|
|
|
auto database_file = database_directory + ".db"; |
|
|
|
Database db; |
|
|
|
auto const database_file = database_directory + ".db"; |
|
|
|
|
|
|
|
if (!boost::filesystem::exists(database_file)){ |
|
|
|
fs::path directory(database_directory); |
|
|
|
fs::path const directory(database_directory); |
|
|
|
fs::directory_iterator eod; |
|
|
|
for(fs::directory_iterator it(directory); it != eod; ++it){ |
|
|
|
auto && path = it->path(); |
|
|
|
auto ext = path.extension(); |
|
|
|
auto const path = it->path(); |
|
|
|
auto const ext = path.extension(); |
|
|
|
if(ext != ".png" && ext != ".jpg") continue; |
|
|
|
|
|
|
|
cout << colors::green("adding: ") << path.string() << endl; |
|
|
@ -50,7 +53,6 @@ Database read_database(string const & database_directory){ |
|
|
|
} else { |
|
|
|
ifstream file(database_file); |
|
|
|
ar::binary_iarchive archive(file); |
|
|
|
// read class state from archive
|
|
|
|
archive >> db; |
|
|
|
} |
|
|
|
|
|
|
@ -59,10 +61,10 @@ Database read_database(string const & database_directory){ |
|
|
|
} |
|
|
|
|
|
|
|
Mozaic create_mozaic(Database const & db, string const & filename, int h_tiles, int v_tiles){ |
|
|
|
map<pair<int, int>, string> mozaic; |
|
|
|
Mozaic mozaic; |
|
|
|
|
|
|
|
apply_to_tiles("image.jpg", h_tiles, v_tiles, [&](int c, int r, raw_rgb_image const & image){ |
|
|
|
auto index = db.nearest_image(image); |
|
|
|
apply_to_tiles("image.jpg", h_tiles, v_tiles, [&](int c, int r, av::frame const & frame){ |
|
|
|
auto const index = db.nearest_image(frame); |
|
|
|
cout << colors::red("tile ") << c << ", " << r << ": " << db.filename(index) << endl; |
|
|
|
mozaic[make_pair(c, r)] = db.filename(index); |
|
|
|
}); |
|
|
@ -71,11 +73,8 @@ Mozaic create_mozaic(Database const & db, string const & filename, int h_tiles, |
|
|
|
} |
|
|
|
|
|
|
|
void save_mozaic(Mozaic const & mozaic, string filename, int h_tiles, int v_tiles){ |
|
|
|
const auto pix_fmt = AV_PIX_FMT_YUVJ444P; |
|
|
|
const auto codec_id= AV_CODEC_ID_MJPEG; |
|
|
|
|
|
|
|
int tile_width = 128; |
|
|
|
int tile_height = 128; |
|
|
|
auto const pix_fmt = AV_PIX_FMT_YUVJ444P; |
|
|
|
auto const codec_id= AV_CODEC_ID_MJPEG; |
|
|
|
|
|
|
|
// Open all files we need
|
|
|
|
map<string, av::frame> frames; |
|
|
@ -85,8 +84,8 @@ void save_mozaic(Mozaic const & mozaic, string filename, int h_tiles, int v_tile |
|
|
|
frames.emplace(x.second, crop_to_square(open_image(x.second))); |
|
|
|
} |
|
|
|
|
|
|
|
auto total_width = h_tiles * tile_width; |
|
|
|
auto total_height = v_tiles * tile_height; |
|
|
|
auto const total_width = h_tiles * tile_width; |
|
|
|
auto const total_height = v_tiles * tile_height; |
|
|
|
|
|
|
|
// Create output frame
|
|
|
|
std::vector<uint8_t, av::allocator<uint8_t>> data(make_u(avpicture_get_size(pix_fmt, total_width, total_height)), 0); |
|
|
@ -128,9 +127,9 @@ void save_mozaic(Mozaic const & mozaic, string filename, int h_tiles, int v_tile |
|
|
|
codec_ctx->time_base = av_make_q(1, 1); |
|
|
|
auto opened_codec = av::codec_open(codec_ctx.get(), codec, nullptr); |
|
|
|
|
|
|
|
const auto buffer_size = avpicture_get_size(pix_fmt, codec_ctx->width, codec_ctx->height); |
|
|
|
auto const buffer_size = avpicture_get_size(pix_fmt, codec_ctx->width, codec_ctx->height); |
|
|
|
std::vector<uint8_t> buffer(make_u(buffer_size), 0); |
|
|
|
auto output_size = avcodec_encode_video(codec_ctx.get(), buffer.data(), buffer_size, frame.get()); |
|
|
|
auto const output_size = avcodec_encode_video(codec_ctx.get(), buffer.data(), buffer_size, frame.get()); |
|
|
|
assert(output_size <= buffer_size); |
|
|
|
cout << "output size" << output_size << endl; |
|
|
|
|
|
|
@ -142,14 +141,14 @@ void save_mozaic(Mozaic const & mozaic, string filename, int h_tiles, int v_tile |
|
|
|
int main(){ |
|
|
|
av_register_all(); |
|
|
|
|
|
|
|
string database_directory = "database"; |
|
|
|
string filename = "image.jpg"; |
|
|
|
string output = "output.jpg"; |
|
|
|
int h_tiles = 4 * 13; |
|
|
|
int v_tiles = 3 * 13; |
|
|
|
string const database_directory = "database"; |
|
|
|
string const filename = "image.jpg"; |
|
|
|
string const output = "output.jpg"; |
|
|
|
int const h_tiles = 4 * 7; |
|
|
|
int const v_tiles = 3 * 7; |
|
|
|
|
|
|
|
const auto db = read_database(database_directory); |
|
|
|
const auto mozaic = create_mozaic(db, filename, h_tiles, v_tiles); |
|
|
|
auto const db = read_database(database_directory); |
|
|
|
auto const mozaic = create_mozaic(db, filename, h_tiles, v_tiles); |
|
|
|
save_mozaic(mozaic, output, h_tiles, v_tiles); |
|
|
|
|
|
|
|
// debugging
|
|
|
|