Skip to content

Commit 91b18b4

Browse files
committed
fixed stupid bugs in habitat, kinda stable, still not great but this might be as good as it gets with no overlapping
1 parent ee5c2a5 commit 91b18b4

File tree

6 files changed

+231
-33
lines changed

6 files changed

+231
-33
lines changed

main.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,23 @@ int main( int argc, char* args[] ) {
3838

3939
std::vector<SrcImage> src_images;
4040
load_images("hemtai", src_images);
41-
SrcImage reconstructed = src_images[src_images.size()-1];
42-
src_images.pop_back();
41+
int recInd = src_images.size()-4;
42+
SrcImage reconstructed = src_images[recInd];
43+
std::cout << "RECONSTRUCTING " << reconstructed.path << std::endl;
44+
src_images.erase(src_images.begin() + recInd);
4345
Habitat hbsim = Habitat(&reconstructed, &src_images);
4446

4547
Timer t;
4648
t.start();
4749
for (int i = 0; i < 100000000; i++) {
4850
hbsim.step();
49-
50-
if (i % 10 == 0) {
51-
while (SDL_PollEvent(&event)) {
52-
}
51+
while (SDL_PollEvent(&event)) {
52+
}
53+
if (i % 500 == 0) {
5354
sdl_draw(renderer, reconstructed, (void*)hbsim.getBestGroup().pastedData);
54-
std::cout << "currently at " << i << " 100 gens took " << t.get() <<
55-
"\n" << "sad is " << hbsim.getBestGroup().fitness << "\n";
55+
std::cout << "currently at " << i << " 500 gens took " << t.get() <<
56+
"\n" << "sad is " << hbsim.getBestGroup().fitness <<
57+
" num images :" << hbsim.getBestGroup().individuals.size() << "\n";
5658

5759
t.start();
5860
}
@@ -91,6 +93,7 @@ void sdl_draw(SDL_Renderer* renderer, const SrcImage& img, void* data) {
9193
SDL_TEXTUREACCESS_STREAMING, img.width, img.height);
9294
SDL_UpdateTexture(intermediate, NULL, data, img.pitch);
9395

96+
SDL_SetRenderDrawColor(renderer, 88, 88, 88, 255);
9497
SDL_RenderClear(renderer);
9598
SDL_RenderCopy(renderer, intermediate, NULL, NULL);
9699
SDL_RenderPresent(renderer);

main_pure_random.cpp

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#include <SDL.h>
2+
#include <SDL_image.h>
3+
4+
#include <iostream>
5+
#include <cmath>
6+
7+
#include <windows.h>
8+
#include <winuser.h>
9+
10+
#include <random>
11+
12+
#include "Timer.h"
13+
#include <rotate.h>
14+
#include <math.h>
15+
#include <execution>
16+
17+
#include <opencv2/core/core.hpp>
18+
#include <opencv2/core/matx.hpp>
19+
#include <opencv2/core/mat.hpp>
20+
#include "opencv2/opencv.hpp"
21+
#include <opencv2/imgcodecs.hpp>
22+
23+
#include "utils.h"
24+
25+
bool init_sdl(SDL_Window** window_ptr, SDL_Surface** surface_ptr, SDL_Renderer** renderer_ptr,
26+
int x_win_res, int y_win_res);
27+
void sdl_draw(SDL_Renderer* renderer, const SrcImage& img);
28+
29+
int main( int argc, char* args[] ) {
30+
SDL_Window* window = NULL;
31+
SDL_Surface* screenSurface = NULL;
32+
SDL_Renderer* renderer = NULL;
33+
SDL_Event event;
34+
init_sdl(&window, &screenSurface, &renderer, 400, 400);
35+
IMG_Init(IMG_INIT_PNG);
36+
37+
std::vector<SrcImage> src_images;
38+
load_images("imgsimple", src_images);
39+
int recInd = src_images.size()-1;
40+
SrcImage reconstructed = src_images[recInd];
41+
reconstructed.data = new uint8_t[reconstructed.width * reconstructed.height * 4];
42+
memset(reconstructed.data, 0xFFFFFF00, reconstructed.width * reconstructed.height*4);
43+
RotatePixel_t *pPstBase = static_cast<RotatePixel_t*>((void*)reconstructed.data);
44+
RotatePixel_t *pDstBase = static_cast<RotatePixel_t*>((void*)src_images[recInd].data);
45+
46+
Timer t;
47+
t.start();
48+
for (int i = 0; i < 100000000; i++) {
49+
int index = rand()%(src_images.size());
50+
if (index == recInd) {
51+
continue;
52+
}
53+
RotatePixel_t *pSrcBase = static_cast<RotatePixel_t*>((void*)src_images[index].data);
54+
int best_sad = INT_MAX;
55+
int bestX;
56+
int bestY;
57+
float bestA;
58+
float bestS;
59+
for (int j = 0; j < 100; j++) {
60+
int fDstCX = rand()%(src_images[recInd].width);
61+
int fDstCY = rand()%(src_images[recInd].height);
62+
float fAngle = rand()%(314) / 100.0;
63+
float fScale = (rand()%(1500) + 1) / 1000.0;
64+
sadPair genQuality = RotateDrawClipSad(
65+
pDstBase, src_images[recInd].width, src_images[recInd].height, src_images[recInd].pitch,
66+
pSrcBase, src_images[index].width, src_images[index].height, src_images[index].pitch,
67+
pPstBase,
68+
fDstCX, fDstCY,
69+
0, 0,
70+
fAngle, fScale );
71+
if (genQuality.sad1 < genQuality.sad2 && genQuality.sad1 < best_sad) {
72+
best_sad = genQuality.sad1;
73+
bestX = fDstCX;
74+
bestY = fDstCY;
75+
bestA = fAngle;
76+
bestS = fScale;
77+
}
78+
}
79+
80+
if (best_sad != INT_MAX) {
81+
RotateDrawClip(
82+
pPstBase, src_images[recInd].width, src_images[recInd].height, src_images[recInd].pitch,
83+
pSrcBase, src_images[index].width, src_images[index].height, src_images[index].pitch,
84+
bestX, bestY,
85+
0, 0,
86+
bestA, bestS );
87+
}
88+
if (i % 100 == 0) {
89+
while (SDL_PollEvent(&event)) {
90+
}
91+
sdl_draw(renderer, reconstructed);
92+
std::cout << "currently at " << i << " 100 gens took " << t.get() <<
93+
"\n" << "sad is " << compute_sad(src_images[0].data,
94+
reconstructed.data,
95+
reconstructed.width * reconstructed.height * 4) << "\n";
96+
97+
t.start();
98+
}
99+
}
100+
101+
return 0;
102+
}
103+
104+
105+
bool init_sdl(SDL_Window** window_ptr, SDL_Surface** surface_ptr, SDL_Renderer** renderer_ptr,
106+
int x_win_res, int y_win_res) {
107+
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
108+
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
109+
return false;
110+
}
111+
112+
*window_ptr = SDL_CreateWindow( "imageVimage", SDL_WINDOWPOS_UNDEFINED,
113+
SDL_WINDOWPOS_UNDEFINED, x_win_res,
114+
y_win_res, SDL_WINDOW_SHOWN );
115+
if( *window_ptr == NULL ) {
116+
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
117+
return false;
118+
}
119+
120+
*renderer_ptr = SDL_CreateRenderer( *window_ptr, -1, SDL_RENDERER_ACCELERATED );
121+
122+
SDL_SetRenderDrawColor( *renderer_ptr, 0xFF, 0xFF, 0xFF, 0xFF );
123+
124+
*surface_ptr = SDL_GetWindowSurface( *window_ptr );
125+
126+
return true;
127+
}
128+
129+
void sdl_draw(SDL_Renderer* renderer, const SrcImage& img) {
130+
SDL_Texture *intermediate = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
131+
SDL_TEXTUREACCESS_STREAMING, img.width, img.height);
132+
SDL_UpdateTexture(intermediate, NULL, (void*)img.data, 4 * img.width);
133+
134+
SDL_RenderClear(renderer);
135+
SDL_RenderCopy(renderer, intermediate, NULL, NULL);
136+
SDL_RenderPresent(renderer);
137+
138+
SDL_Delay(0);
139+
SDL_DestroyTexture(intermediate);
140+
}

src/Habitat.cpp

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <random>
66
#include <math.h>
77
#include <execution>
8+
#include <iostream>
89

910
bool cmp(const PopulationGroup& a, const PopulationGroup& b) {
1011
return a.fitness < b.fitness;
@@ -19,25 +20,34 @@ Habitat::Habitat(const SrcImage* reconstructionImage, const std::vector<SrcImage
1920
mReconstructionImage = reconstructionImage;
2021
mSettings = settings;
2122
init_pop();
23+
24+
/*
25+
std::vector<int> indexes;
26+
for(int i=0; i<mSettings.popSize; i++) {
27+
indexes.push_back(i);
28+
}
29+
30+
std::for_each(std::execution::par_unseq, indexes.begin(), indexes.end(), [&](int i) {
31+
drawComputeFit(mPopulation[i]);
32+
}); */
2233
}
2334

2435
void Habitat::step() {
2536
std::sort(mPopulation.begin(), mPopulation.end(), cmp);
2637

2738
std::vector<int> indexes;
2839
for(int i=0; i<mSettings.popSize; i++) {
29-
if(i>mSettings.popSize - ceil(mSettings.popSize * mSettings.reroll)) {
40+
if(i>(mSettings.popSize - ceil(mSettings.popSize * mSettings.reroll) - 1)) {
3041
indexes.push_back(i);
31-
}
42+
}
3243
}
3344

3445
std::for_each(std::execution::par_unseq, indexes.begin(), indexes.end(), [&](int i) {
3546
if(rand()%100 < mSettings.crossoverChance) {
36-
int ind1 = rand() % mSettings.popSize;
37-
int ind2 = rand() % mSettings.popSize;
47+
int ind1 = rand() % (int)(mSettings.popSize - ceil(mSettings.popSize * mSettings.reroll) - 1);
48+
int ind2 = rand() % (int)(mSettings.popSize - ceil(mSettings.popSize * mSettings.reroll) - 1);
3849
crossover(mPopulation[ind1], mPopulation[ind2], mPopulation[i]);
39-
}
40-
else {
50+
} else {
4151
mutate(mPopulation[i]);
4252
}
4353

@@ -53,7 +63,7 @@ void Habitat::init_pop() {
5363
mPopulation.clear();
5464
for (int i = 0; i < mSettings.popSize; i++) {
5565
mPopulation.push_back(PopulationGroup{});
56-
mPopulation[i].pastedData = new uint8_t[mReconstructionImage->pitch*mReconstructionImage->height];
66+
mPopulation[i].pastedData = new uint8_t[mReconstructionImage->width*mReconstructionImage->height*4];
5767
mPopulation[i].fitness = UINT32_MAX;
5868
for (int j = 0; j < mSettings.imgCount; j++) {
5969
mPopulation[i].individuals.push_back(random_individual());
@@ -62,11 +72,11 @@ void Habitat::init_pop() {
6272
}
6373

6474
void Habitat::drawComputeFit(PopulationGroup& grp) {
65-
memset(grp.pastedData, 0xFFFFFF00, mReconstructionImage->width*mReconstructionImage->height);
75+
memset(grp.pastedData, 0xFF, mReconstructionImage->width*mReconstructionImage->height*4);
6676

6777
RotatePixel_t *pDstBase = static_cast<RotatePixel_t*>((void*)grp.pastedData);
6878

69-
for (int i = 0; i < mSettings.imgCount; i++) {
79+
for (int i = 0; i < grp.individuals.size(); i++) {
7080
const SrcImage* pImg = grp.individuals[i].img;
7181
RotatePixel_t *pSrcBase = static_cast<RotatePixel_t*>((void*)pImg->data);
7282
RotateDrawClip(pDstBase, mReconstructionImage->width, mReconstructionImage->height, mReconstructionImage->pitch,
@@ -77,27 +87,56 @@ void Habitat::drawComputeFit(PopulationGroup& grp) {
7787
}
7888

7989
grp.fitness = compute_sad(grp.pastedData, mReconstructionImage->data,
80-
mReconstructionImage->pitch*mReconstructionImage->height);
90+
mReconstructionImage->width*mReconstructionImage->height*4);
8191
}
8292

8393
void Habitat::crossover(const PopulationGroup& grpA, const PopulationGroup& grpB, PopulationGroup& grpC) {
84-
for (int i = 0; i < mSettings.imgCount; i++) {
94+
grpC.individuals.clear();
95+
for (int i = 0; i < std::min(grpA.individuals.size(),
96+
grpB.individuals.size()); i++) {
8597
if (rand()%2) {
86-
grpC.individuals[i] = grpA.individuals[i];
98+
grpC.individuals.push_back(grpA.individuals[i]);
8799
} else {
88-
grpC.individuals[i] = grpB.individuals[i];
100+
grpC.individuals.push_back(grpB.individuals[i]);
89101
}
90102
}
91103
}
92104

93105
void Habitat::mutate(PopulationGroup& grp) {
94-
for (int i = 0; i < mSettings.imgCount; i++) {
95-
grp.individuals[i].angle += rand()%50 / 100.0;
106+
int roll = rand()%100;
107+
if (roll < 60) {
108+
mutateAdjust(grp);
109+
} else if (roll < 85) {
110+
mutateAdd(grp);
111+
} else {
112+
mutateRemove(grp);
113+
}
114+
}
115+
116+
void Habitat::mutateAdd(PopulationGroup& grp) {
117+
grp.individuals.push_back(random_individual());
118+
}
119+
120+
void Habitat::mutateRemove(PopulationGroup& grp) {
121+
if (grp.individuals.size() == 0)
122+
return;
123+
124+
int ind = rand()%grp.individuals.size();
125+
grp.individuals.erase(grp.individuals.begin() + ind);
126+
}
127+
128+
void Habitat::mutateAdjust(PopulationGroup& grp) {
129+
//for (int i = 0; i < grp.individuals.size(); i++) {
130+
{
131+
int i = rand()%grp.individuals.size();
132+
// ADD CLOSEST IMAGES
133+
134+
grp.individuals[i].angle += rand()%50 / 100.0 * std::pow(-1, rand()%2);
96135
grp.individuals[i].x += rand()%(mReconstructionImage->width) * 0.1 * std::pow(-1, rand()%2);
97136
grp.individuals[i].y += rand()%(mReconstructionImage->height) * 0.1 * std::pow(-1, rand()%2);
98-
float randScale = (rand()%((int)(100*mSettings.maxScale - 100*mSettings.minScale))
99-
+ (100*mSettings.minScale)) / 100.0;
100-
grp.individuals[i].scale += randScale * 0.3 * std::pow(-1, rand()%2);
137+
float randScale = (rand()%((int)(1000*mSettings.maxScale - 1000*mSettings.minScale))
138+
+ (1000*mSettings.minScale)) / 1000.0;
139+
grp.individuals[i].scale += randScale * 0.1 * std::pow(-1, rand()%2);
101140
if (grp.individuals[i].scale < mSettings.minScale) {
102141
grp.individuals[i].scale = mSettings.minScale;
103142
} else if (grp.individuals[i].scale > mSettings.maxScale) {
@@ -116,14 +155,15 @@ Individual Habitat::random_individual() {
116155
float angle;
117156
float scale;
118157

119-
newIndiv.imgID = rand()%mRefImages->size();
158+
newIndiv.imgID = rand()%(mRefImages->size());
120159
newIndiv.img = &(*mRefImages)[newIndiv.imgID];
121160

122-
newIndiv.x = rand()%(mReconstructionImage->width - 10) + 5;
123-
newIndiv.y = rand()%(mReconstructionImage->height - 10) + 5;
161+
newIndiv.x = rand()%(mReconstructionImage->width);
162+
newIndiv.y = rand()%(mReconstructionImage->height);
124163
newIndiv.angle = rand()%(314) / 100.0;
125-
newIndiv.scale = (rand()%((int)(100*mSettings.maxScale - 100*mSettings.minScale))
126-
+ (100*mSettings.minScale)) / 100.0;
164+
newIndiv.scale = (rand()%((int)(1000*mSettings.maxScale - 1000*mSettings.minScale))
165+
+ (1000*mSettings.minScale)) / 1000.0;
166+
//newIndiv.scale = mSettings.minScale;
127167

128168
return newIndiv;
129169

src/Habitat.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "utils.h"
55
#include "vector"
66

7-
#define SETTINGS_DEFAULT Settings{200, 20, 0.75, 90, 0.2, 2}
7+
#define SETTINGS_DEFAULT Settings{12, 30, 0.7, 70, 0.001, 1}
88

99
struct Individual {
1010
const SrcImage* img;
@@ -53,6 +53,9 @@ class Habitat
5353
void crossover(const PopulationGroup& grpA, const PopulationGroup& grpB, PopulationGroup& grpC);
5454
void drawComputeFit(PopulationGroup& grp);
5555
void mutate(PopulationGroup& grp);
56+
void mutateAdjust(PopulationGroup& grp);
57+
void mutateAdd(PopulationGroup& grp);
58+
void mutateRemove(PopulationGroup& grp);
5659
};
5760

5861
#endif // HABITAT_H

src/utils.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,17 @@ int compute_sad(uint8_t* image, uint8_t* target, size_t num_bytes) {
8686
return sum;
8787
}
8888

89+
int compute_sse_naive(uint8_t* image, uint8_t* target, size_t num_bytes) {
90+
int sum = 0;
91+
92+
for (int i = 0; i < num_bytes; i++) {
93+
int dif = image[i] - target[i];
94+
sum += dif * dif;
95+
}
96+
97+
return sum;
98+
}
99+
89100
void simd_memcpy(uint8_t* dst, uint8_t* src, size_t num_bytes) {
90101
// should i convert this to uint32_t ?
91102
// I think benchmarks did not show significant improvement

src/utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <vector>
66

77
//TODO: do this better
8-
#define PIXELS_PER_IMAGE 50000.0
8+
#define PIXELS_PER_IMAGE 30000.0
99

1010
/* Img utils */
1111
typedef struct SrcImage {
@@ -22,6 +22,7 @@ void load_images(std::string path, std::vector<SrcImage>&images);
2222
/* Math utils */
2323
int compute_sad(uint8_t* image, uint8_t* target, size_t num_bytes);
2424
int compute_sad_naive(uint8_t* image, uint8_t* target, size_t num_bytes);
25+
int compute_sse_naive(uint8_t* image, uint8_t* target, size_t num_bytes);
2526
void simd_memcpy(uint8_t* dst, uint8_t* src, size_t num_bytes);
2627

2728
#endif // UTILS_H

0 commit comments

Comments
 (0)