[TASK] Implement real gauss filter, fix the whole thing up.
This commit is contained in:
parent
6f70f12946
commit
94e32cd4b9
@ -27,6 +27,7 @@ class CannyEdgeMachine {
|
|||||||
|
|
||||||
// Params
|
// Params
|
||||||
int filter_size;
|
int filter_size;
|
||||||
|
double filter_sigma;
|
||||||
double t_low;
|
double t_low;
|
||||||
double t_high;
|
double t_high;
|
||||||
|
|
||||||
@ -54,8 +55,9 @@ class CannyEdgeMachine {
|
|||||||
free(this->gradient_y);
|
free(this->gradient_y);
|
||||||
};
|
};
|
||||||
|
|
||||||
void setGaussFilterSize(int filter_size) {
|
void setGaussFilterParams(int filter_size, double filter_sigma) {
|
||||||
this->filter_size = filter_size;
|
this->filter_size = filter_size;
|
||||||
|
this->filter_sigma = filter_sigma;
|
||||||
};
|
};
|
||||||
|
|
||||||
void setThresholdValues(double t_low, double t_high) {
|
void setThresholdValues(double t_low, double t_high) {
|
||||||
@ -73,26 +75,33 @@ class CannyEdgeMachine {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void doGaussBlur(int filter_width) {
|
double gauss(int x, int y, double sigma) {
|
||||||
|
// e^-((x^2 + y^2)/(sigma^2))
|
||||||
|
double upper_part = pow(M_E, (-1.0) * ( (pow(x, 2)+pow(y, 2))/pow(sigma, 2) ) );
|
||||||
|
return upper_part;
|
||||||
|
};
|
||||||
|
|
||||||
|
void doGaussBlur(void) {
|
||||||
|
int filter_width = this->filter_size;
|
||||||
|
double sigma = this->filter_sigma;
|
||||||
// build the gauss filter
|
// build the gauss filter
|
||||||
int* filter = (int*) malloc(sizeof(int) * filter_width * filter_width);
|
double* filter = (double*) malloc(sizeof(double) * filter_width * filter_width);
|
||||||
int sum_weights = 0;
|
double sum_weights = 0;
|
||||||
int filter_middle = (filter_width)/2;
|
std::cout << "Using gauss filter: " << std::endl;
|
||||||
for(int x=0; x<filter_width; x++) {
|
for(int x=0; x<filter_width; x++) {
|
||||||
int i = x;
|
|
||||||
if(x > filter_middle) i = filter_middle - (x - filter_middle);
|
|
||||||
for(int y=0; y<filter_width; y++) {
|
for(int y=0; y<filter_width; y++) {
|
||||||
int j = y;
|
filter[x*filter_width + y] = this->gauss(x, y, sigma);
|
||||||
if(y > filter_middle) j = filter_middle - (y - filter_middle);
|
sum_weights += filter[x*filter_width + y];
|
||||||
filter[i*filter_width + j] = pow(2, i) * pow(2, j);
|
std::cout << "(" << x << ", " << y << ") " << filter[x*filter_width + y] << " | ";
|
||||||
sum_weights += filter[i*filter_width + j];
|
|
||||||
}
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
std::cout << std::endl << "Sum weights: " << sum_weights << std::endl;
|
||||||
// apply gauss filter
|
// apply gauss filter
|
||||||
int filter_offset = (filter_width+1)/2;
|
int filter_offset = (filter_width+1)/2;
|
||||||
for(int x=(0+filter_offset); x<(this->width-filter_offset); x++) {
|
for(int x=(0+filter_offset); x<(this->width-filter_offset); x++) {
|
||||||
for(int y=(0+filter_offset); y<(this->height-filter_offset); y++) {
|
for(int y=(0+filter_offset); y<(this->height-filter_offset); y++) {
|
||||||
int sum_intensity = 0;
|
double sum_intensity = 0.0;
|
||||||
int h, s, l;
|
int h, s, l;
|
||||||
for(int fx=0; fx<filter_width; fx++) {
|
for(int fx=0; fx<filter_width; fx++) {
|
||||||
int dx = fx - (filter_width / 2);
|
int dx = fx - (filter_width / 2);
|
||||||
@ -105,7 +114,7 @@ class CannyEdgeMachine {
|
|||||||
}
|
}
|
||||||
QColor color = QColor::fromRgb(this->original->getPixel(x, y, LazyImage::DEFAULT));
|
QColor color = QColor::fromRgb(this->original->getPixel(x, y, LazyImage::DEFAULT));
|
||||||
color.getHsl(&h, &s, &l);
|
color.getHsl(&h, &s, &l);
|
||||||
l = qRound((1.0*sum_intensity) / (1.0*sum_weights));
|
l = qRound(sum_intensity/sum_weights);
|
||||||
if(l > 255) l = 255;
|
if(l > 255) l = 255;
|
||||||
if(l < 0) l = 0;
|
if(l < 0) l = 0;
|
||||||
color.setHsl(h, s, l);
|
color.setHsl(h, s, l);
|
||||||
@ -132,7 +141,7 @@ class CannyEdgeMachine {
|
|||||||
sum_intensity = 0;
|
sum_intensity = 0;
|
||||||
for(int i=0; i<gradiant_size; i++) {
|
for(int i=0; i<gradiant_size; i++) {
|
||||||
int dx = i - gradiant_offset;
|
int dx = i - gradiant_offset;
|
||||||
QColor color = QColor::fromRgb(this->original->getPixel(x+dx, y, LazyImage::DEFAULT));
|
QColor color = QColor::fromRgb(this->working_copy->getPixel(x+dx, y, LazyImage::DEFAULT));
|
||||||
color.getHsl(&h, &s, &l);
|
color.getHsl(&h, &s, &l);
|
||||||
sum_intensity += l * gradiant_vector[i];
|
sum_intensity += l * gradiant_vector[i];
|
||||||
}
|
}
|
||||||
@ -141,7 +150,7 @@ class CannyEdgeMachine {
|
|||||||
sum_intensity = 0;
|
sum_intensity = 0;
|
||||||
for(int i=0; i<gradiant_size; i++) {
|
for(int i=0; i<gradiant_size; i++) {
|
||||||
int dy = i - gradiant_offset;
|
int dy = i - gradiant_offset;
|
||||||
QColor color = QColor::fromRgb(this->original->getPixel(x, y+dy, LazyImage::DEFAULT));
|
QColor color = QColor::fromRgb(this->working_copy->getPixel(x, y+dy, LazyImage::DEFAULT));
|
||||||
color.getHsl(&h, &s, &l);
|
color.getHsl(&h, &s, &l);
|
||||||
sum_intensity += l * gradiant_vector[i];
|
sum_intensity += l * gradiant_vector[i];
|
||||||
}
|
}
|
||||||
@ -271,7 +280,7 @@ class CannyEdgeMachine {
|
|||||||
|
|
||||||
void work() {
|
void work() {
|
||||||
this->reset();
|
this->reset();
|
||||||
this->doGaussBlur(this->filter_size); // uses filter_size
|
this->doGaussBlur(); // uses filter_size, filter_sigma
|
||||||
this->doGradiants();
|
this->doGradiants();
|
||||||
this->doGradiantMagnitude();
|
this->doGradiantMagnitude();
|
||||||
// TODO: Checkpoint for 'before t_low changed'
|
// TODO: Checkpoint for 'before t_low changed'
|
||||||
|
@ -651,11 +651,12 @@ void ImageViewer::applyBasicFilterWithOverflowHandling() {
|
|||||||
void ImageViewer::runCannyEdge(void) {
|
void ImageViewer::runCannyEdge(void) {
|
||||||
CannyEdgeMachine cem = CannyEdgeMachine(original, working_copy);
|
CannyEdgeMachine cem = CannyEdgeMachine(original, working_copy);
|
||||||
int filter_size = gauss_filter_size->value();
|
int filter_size = gauss_filter_size->value();
|
||||||
|
double filter_sigma = gauss_filter_sigma->value();
|
||||||
double t_low = t_low_spinbox->value();
|
double t_low = t_low_spinbox->value();
|
||||||
double t_high = t_high_spinbox->value();
|
double t_high = t_high_spinbox->value();
|
||||||
logFile << "Canny-Edge using N*N filter size: " << filter_size << ", and thresholds: " << t_low << ", " << t_high << std::endl;
|
logFile << "Canny-Edge using N*N filter size: " << filter_size << ", filter sigma: " << filter_sigma << ", and thresholds: " << t_low << ", " << t_high << std::endl;
|
||||||
renewLogging();
|
renewLogging();
|
||||||
cem.setGaussFilterSize(filter_size);
|
cem.setGaussFilterParams(filter_size, filter_sigma);
|
||||||
cem.setThresholdValues(t_low, t_high);
|
cem.setThresholdValues(t_low, t_high);
|
||||||
cem.work();
|
cem.work();
|
||||||
updateImageDisplay();
|
updateImageDisplay();
|
||||||
@ -929,6 +930,10 @@ void ImageViewer::generateControlPanels() {
|
|||||||
gauss_filter_size->setMinimum(3);
|
gauss_filter_size->setMinimum(3);
|
||||||
gauss_filter_size->setValue(3);
|
gauss_filter_size->setValue(3);
|
||||||
|
|
||||||
|
gauss_filter_sigma = new QDoubleSpinBox();
|
||||||
|
gauss_filter_sigma->setDecimals(5);
|
||||||
|
gauss_filter_sigma->setValue(1.4);
|
||||||
|
|
||||||
t_low_spinbox = new QDoubleSpinBox();
|
t_low_spinbox = new QDoubleSpinBox();
|
||||||
t_low_spinbox->setDecimals(5);
|
t_low_spinbox->setDecimals(5);
|
||||||
t_low_spinbox->setValue(2.0);
|
t_low_spinbox->setValue(2.0);
|
||||||
@ -939,6 +944,8 @@ void ImageViewer::generateControlPanels() {
|
|||||||
|
|
||||||
task_tab5_scrolllayout->addWidget(new QLabel("Gauss filter size (NxN)"));
|
task_tab5_scrolllayout->addWidget(new QLabel("Gauss filter size (NxN)"));
|
||||||
task_tab5_scrolllayout->addWidget(gauss_filter_size);
|
task_tab5_scrolllayout->addWidget(gauss_filter_size);
|
||||||
|
task_tab5_scrolllayout->addWidget(new QLabel("Gauss filter sigma"));
|
||||||
|
task_tab5_scrolllayout->addWidget(gauss_filter_sigma);
|
||||||
task_tab5_scrolllayout->addWidget(new QLabel("Low threshold value"));
|
task_tab5_scrolllayout->addWidget(new QLabel("Low threshold value"));
|
||||||
task_tab5_scrolllayout->addWidget(t_low_spinbox);
|
task_tab5_scrolllayout->addWidget(t_low_spinbox);
|
||||||
task_tab5_scrolllayout->addWidget(new QLabel("High threshold value"));
|
task_tab5_scrolllayout->addWidget(new QLabel("High threshold value"));
|
||||||
|
@ -148,6 +148,7 @@ class ImageViewer : public QMainWindow {
|
|||||||
QVBoxLayout* task_tab5_scrolllayout;
|
QVBoxLayout* task_tab5_scrolllayout;
|
||||||
|
|
||||||
QDoubleSpinBox* gauss_filter_size;
|
QDoubleSpinBox* gauss_filter_size;
|
||||||
|
QDoubleSpinBox* gauss_filter_sigma;
|
||||||
QDoubleSpinBox* t_low_spinbox;
|
QDoubleSpinBox* t_low_spinbox;
|
||||||
QDoubleSpinBox* t_high_spinbox;
|
QDoubleSpinBox* t_high_spinbox;
|
||||||
QPushButton* run_canny_edge;
|
QPushButton* run_canny_edge;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user