Skip to content

Commit 4716316

Browse files
committed
single option optimization working
1 parent 49a7a9e commit 4716316

File tree

4 files changed

+59
-39
lines changed

4 files changed

+59
-39
lines changed

App/Components/Optimalization/Optimaliation.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
/**
2525
* Function aims to sequentially change single option to find the best match for user image
2626
*/
27-
void single_option_optimization(cv::Mat &img, AlgorithmOptions &options, std::string option_class, size_t option_index, bool uneven = false, int max_iterations=50, double resolution = 0.2);
27+
void single_option_optimization(cv::Mat &img, AlgorithmOptions &options, std::string option_class, size_t option_index, bool uneven = false, int max_iterations=50, int min_start = 1, double resolution = 0.2);
2828

2929
/**
3030
* Function reads the mask saved in image and saves it in variable
@@ -36,24 +36,24 @@
3636
*/
3737
double calculate_intersection_over_union(cv::Mat &image);
3838

39+
//Function runs the watershed segmentation with given options and returns a mask
40+
void simulate_watershed(cv::Mat &img, cv::Mat &out, AlgorithmOptions &options);
41+
3942
private:
4043

4144
//Function finds unique values in matrix and stores it in a vector
4245
void find_unique_values(cv::Mat &matrix, std::vector<int> &storage);
4346

4447
//Function adds one, or creates a new record with a certain object_id
45-
void sum_up_storage(std::map<int,int> &storage, int object_value);
46-
47-
//Function runs the watershed segmentation with given options and returns a mask
48-
void simulate_watershed(cv::Mat &img, cv::Mat &out, AlgorithmOptions &options);
48+
void sum_up_storage(std::map<long int,long int> &storage, int object_value);
4949

5050
/**
5151
* This function calculates maximum intersection over union on object (because many objects can overlap the user matrix)
5252
* returns pair, with first being max IoU, and second is the size of the object
5353
* @param object_id object id in USER MASK
5454
* @param matrix image/mask given to compare with USER MASK
5555
*/
56-
std::pair<double,int> calc_intersection_over_union_per_object(int object_id, cv::Mat &matrix);
56+
std::pair<double,long int> calc_intersection_over_union_per_object(int object_id, cv::Mat &matrix);
5757

5858
cv::Mat user_mask_matrix; //OpenCV like connected components matrix for user mask
5959
AlgorithmOptions *options; //Algorithm options

App/Components/Optimalization/Optimization.cpp

+26-26
Original file line numberDiff line numberDiff line change
@@ -25,36 +25,35 @@ void Optimalization::read_user_mask(std::string path_to_mask){
2525

2626
}
2727

28-
void Optimalization::single_option_optimization(cv::Mat &img, AlgorithmOptions &options, std::string option_class, size_t option_index,bool uneven,int max_iterations, double resolution){
28+
void Optimalization::single_option_optimization(cv::Mat &img, AlgorithmOptions &options, std::string option_class, size_t option_index,bool uneven,int max_iterations, int min_start, double resolution){
2929
//Rescale the image to given ratio
3030
const int opt_size = int(img.cols * resolution); //Material should be a square
3131
cv::Mat image, result;
3232
img.copyTo(image);
3333
Transformations::square_and_resize(image,opt_size);
34-
double precision = 1;
35-
int best_val = 0;
34+
double precision = 0.0, new_precision = 0.0;
3635
//get the value of the option, and define max and minimum values.
3736
if(options.get_db_var(option_index,option_class) == AlgorithmOptions::MAX_DB){
3837
//Then we work with integers
3938
//With integers it is easier, just iterate over every value from 0 to 10
4039
simulate_watershed(image,result,options);
40+
int best_val = options.get_int_var(option_index,option_class);
4141
precision = calculate_intersection_over_union(result);
42-
std::cout << "PREC: " << precision << std::endl;
43-
best_val = options.get_int_var(option_index, option_class);
44-
for(int x = 1; x < max_iterations; x++){
42+
for(int x = min_start; x < max_iterations; x++){
4543
if(uneven && x !=1){
4644
x+=1;
4745
}
48-
// options.set_int_value(option_index, option_class, x);
46+
options.set_int_value(option_index, option_class, x);
4947
simulate_watershed(image,result,options);
50-
double new_precision = calculate_intersection_over_union(result);
48+
new_precision = calculate_intersection_over_union(result);
49+
// std::cout << "PRECISION: " << new_precision << std::endl;
5150
if(new_precision > precision){
5251
precision = new_precision;
5352
std:: cout << "Found new best value for " << option_index << " : " << x << " || Precision: " << precision << std::endl;
5453
best_val = x;
5554
}
5655
}
57-
//options.set_int_value(option_index, option_class, best_val);
56+
options.set_int_value(option_index, option_class, best_val);
5857
}
5958
else{
6059

@@ -76,9 +75,9 @@ double Optimalization::calculate_intersection_over_union(cv::Mat &image){
7675
this->find_unique_values(this->user_mask_matrix,unique_in_user_matrix);
7776
//Then, calculate the intersection per object, including it's size
7877
double val_sum = 0;
79-
int pixel_sum = 0;
78+
long int pixel_sum = 0;
8079
for(size_t x = 0; x < unique_in_user_matrix.size(); x++){
81-
std::pair<double,int> result = this->calc_intersection_over_union_per_object(unique_in_user_matrix[x],image);
80+
std::pair<double,long int> result = this->calc_intersection_over_union_per_object(unique_in_user_matrix[x],image);
8281
val_sum += result.first * result.second;
8382
pixel_sum += result.second;
8483
}
@@ -101,7 +100,7 @@ void Optimalization::find_unique_values(cv::Mat &matrix, std::vector<int> &stora
101100
}
102101
}
103102

104-
void Optimalization::sum_up_storage(std::map<int,int> &storage, int object_value){
103+
void Optimalization::sum_up_storage(std::map<long int,long int> &storage, int object_value){
105104
//Find if key already exists
106105
auto it = storage.find(object_value);
107106
if(it == storage.end()){
@@ -114,20 +113,21 @@ void Optimalization::sum_up_storage(std::map<int,int> &storage, int object_value
114113

115114
//I KNOW THIS ALGORITHM CAN BE MORE OPTIMAL, BUT I DID IT THEY WAY I DID IT, SO SCREW IT
116115
//I mean, it could be reduced from in final version O(p(2n^2)), where p=nr of objects in user_mask, to just O(2n^2) ...
117-
std::pair<double,int> Optimalization::calc_intersection_over_union_per_object(int object_id, cv::Mat &matrix){
116+
std::pair<double,long int> Optimalization::calc_intersection_over_union_per_object(int object_id, cv::Mat &matrix){
118117
//Working in O(2(n^2)) time, where n is width=height of matrix
119-
cv::Mat mask = this->user_mask_matrix == object_id;
118+
cv::Mat mask;
119+
cv::compare(this->user_mask_matrix, object_id, mask, cv::CMP_EQ);
120120
if(mask.size() != matrix.size()){
121121
throw std::invalid_argument("Error, trying to compare user mask, and argument mask, they are different in size");
122122
}
123123
//Creating a storage for calculating intersection over union
124-
std::map<int,int> intersection_storage;
125-
std::map<int,int> union_storage;
126-
int overall_matrix = 0;
127-
for(int x=0; x < mask.cols; x++){
128-
for(int y=0;y<mask.rows;y++){
129-
int val_mask = mask.at<int>(x,y);
130-
int val_matrix = matrix.at<int>(x,y);
124+
std::map<long int,long int> intersection_storage;
125+
std::map<long int,long int> union_storage;
126+
long int overall_matrix = 0;
127+
for(int x=0; x < mask.rows; x++){
128+
for(int y=0;y<mask.cols;y++){
129+
int val_mask = mask.at<uchar>(x,y);
130+
int val_matrix = matrix.at<uchar>(x,y);
131131
if(val_mask != 0){
132132
sum_up_storage(intersection_storage,val_matrix);
133133
overall_matrix += 1;
@@ -137,9 +137,9 @@ std::pair<double,int> Optimalization::calc_intersection_over_union_per_object(in
137137
}
138138
}
139139
//Now, find the maximum value of intersection over union, here only the maximum value is in interest
140-
double max_val = 0;
140+
double max_val = 0.0;
141141
for(const auto &iter : intersection_storage){
142-
int key = iter.first;
142+
long int key = iter.first;
143143
if(key == 1)continue; //Exclude background
144144
int to_add = -1;
145145
//Find the same key in union_storage
@@ -150,14 +150,14 @@ std::pair<double,int> Optimalization::calc_intersection_over_union_per_object(in
150150
if(to_add == -1){
151151
to_add = union_val->second;
152152
}
153-
int intersec_value = iter.second;
154-
int union_value = overall_matrix - intersec_value + to_add;
153+
long int intersec_value = iter.second;
154+
long int union_value = overall_matrix - intersec_value + to_add;
155155
double IoU = (double)intersec_value / union_value;
156156
if(IoU > max_val){
157157
max_val = IoU;
158158
}
159159
}
160-
return std::pair<double,int>(max_val,overall_matrix);
160+
return std::pair<double,long int>(max_val,overall_matrix);
161161
}
162162

163163
void Optimalization::simulate_watershed(cv::Mat &img, cv::Mat &out, AlgorithmOptions &options){

App/Components/Watershed/Watershed.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ void Watershed::draw_watershed_lines(cv::Mat &src, cv::Mat &dst, cv::Mat &waters
214214

215215
// Blend the watershed result with the original image using 20% opacity for the result
216216
Mat blended;
217-
addWeighted(imageBGRA, 0.7, result, 0.3, 0, blended); // 80% original + 20% overlay
217+
addWeighted(imageBGRA, 0.5, result, 0.5, 0, blended); // 80% original + 20% overlay
218218
blended.copyTo(dst);
219219
}
220220

App/Utils/TEST/main.cpp

+26-6
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,32 @@ int main(int argc, char **argv){
2121
opt.read_user_mask(user_mask_path);
2222
//Create new mask
2323
AlgorithmOptions options(OPTIONS_PATH.c_str());
24-
cv::Mat image;
25-
image = cv::imread(image_path, cv::IMREAD_GRAYSCALE);
26-
opt.single_option_optimization(image,options,"WATERSHED",4,true);
27-
opt.single_option_optimization(image,options,"WATERSHED",2,true);
28-
opt.single_option_optimization(image,options,"WATERSHED",1,true);
29-
opt.single_option_optimization(image,options,"WATERSHED",0,true);
24+
AlgorithmOptions original(OPTIONS_PATH.c_str());
25+
cv::Mat image = cv::imread(image_path, cv::IMREAD_GRAYSCALE);
26+
opt.single_option_optimization(image,options,"FOREGROUND_MASK",0,true,20);
27+
opt.single_option_optimization(image,options,"FOREGROUND_MASK",1,true,20);
28+
opt.single_option_optimization(image,options,"FOREGROUND_REGIONS",0,true,20);
29+
opt.single_option_optimization(image,options,"WATERSHED",0,true,20);
30+
opt.single_option_optimization(image,options,"FOREGROUND_MASK",2,true,20);
31+
opt.single_option_optimization(image,options,"FOREGROUND_MASK",10,true,500,200);
32+
opt.single_option_optimization(image,options,"FOREGROUND_MASK",3,true,20);
33+
opt.single_option_optimization(image,options,"FOREGROUND_REGIONS",3,true,20);
34+
opt.single_option_optimization(image,options,"WATERSHED",2,true,20);
35+
opt.single_option_optimization(image,options,"FOREGROUND_MASK",8,false,50,10);
36+
opt.single_option_optimization(image,options,"FOREGROUND_MASK",9,false,10);
37+
opt.single_option_optimization(image,options,"FOREGROUND_REGIONS",5,true,20);
38+
opt.single_option_optimization(image,options,"WATERSHED",4,true,20);
39+
opt.single_option_optimization(image,options,"FOREGROUND_MASK",12,false,5);
40+
opt.single_option_optimization(image,options,"FOREGROUND_REGIONS",1,true,20);
41+
opt.single_option_optimization(image,options,"WATERSHED",1,true,20);
42+
cv::Mat result, org_result, mask_result, mask_org;
43+
opt.simulate_watershed(image, mask_result, options);
44+
opt.simulate_watershed(image, mask_org, original);
45+
Watershed::draw_watershed_lines(image, result, mask_result);
46+
Watershed::draw_watershed_lines(image, org_result, mask_org);
47+
cv::imshow("Result optimization", result);
48+
cv::imshow("Beofre Opt", org_result);
49+
cv::waitKey(0);
3050
//
3151
return 0;
3252
}

0 commit comments

Comments
 (0)