[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
|
||||
int filter_size;
|
||||
double filter_sigma;
|
||||
double t_low;
|
||||
double t_high;
|
||||
|
||||
@ -54,8 +55,9 @@ class CannyEdgeMachine {
|
||||
free(this->gradient_y);
|
||||
};
|
||||
|
||||
void setGaussFilterSize(int filter_size) {
|
||||
void setGaussFilterParams(int filter_size, double filter_sigma) {
|
||||
this->filter_size = filter_size;
|
||||
this->filter_sigma = filter_sigma;
|
||||
};
|
||||
|
||||
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
|
||||
int* filter = (int*) malloc(sizeof(int) * filter_width * filter_width);
|
||||
int sum_weights = 0;
|
||||
int filter_middle = (filter_width)/2;
|
||||
double* filter = (double*) malloc(sizeof(double) * filter_width * filter_width);
|
||||
double sum_weights = 0;
|
||||
std::cout << "Using gauss filter: " << std::endl;
|
||||
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++) {
|
||||
int j = y;
|
||||
if(y > filter_middle) j = filter_middle - (y - filter_middle);
|
||||
filter[i*filter_width + j] = pow(2, i) * pow(2, j);
|
||||
sum_weights += filter[i*filter_width + j];
|
||||
filter[x*filter_width + y] = this->gauss(x, y, sigma);
|
||||
sum_weights += filter[x*filter_width + y];
|
||||
std::cout << "(" << x << ", " << y << ") " << filter[x*filter_width + y] << " | ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl << "Sum weights: " << sum_weights << std::endl;
|
||||
// apply gauss filter
|
||||
int filter_offset = (filter_width+1)/2;
|
||||
for(int x=(0+filter_offset); x<(this->width-filter_offset); x++) {
|
||||
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;
|
||||
for(int fx=0; fx<filter_width; fx++) {
|
||||
int dx = fx - (filter_width / 2);
|
||||
@ -105,7 +114,7 @@ class CannyEdgeMachine {
|
||||
}
|
||||
QColor color = QColor::fromRgb(this->original->getPixel(x, y, LazyImage::DEFAULT));
|
||||
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 < 0) l = 0;
|
||||
color.setHsl(h, s, l);
|
||||
@ -132,7 +141,7 @@ class CannyEdgeMachine {
|
||||
sum_intensity = 0;
|
||||
for(int i=0; i<gradiant_size; i++) {
|
||||
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);
|
||||
sum_intensity += l * gradiant_vector[i];
|
||||
}
|
||||
@ -141,7 +150,7 @@ class CannyEdgeMachine {
|
||||
sum_intensity = 0;
|
||||
for(int i=0; i<gradiant_size; i++) {
|
||||
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);
|
||||
sum_intensity += l * gradiant_vector[i];
|
||||
}
|
||||
@ -271,7 +280,7 @@ class CannyEdgeMachine {
|
||||
|
||||
void work() {
|
||||
this->reset();
|
||||
this->doGaussBlur(this->filter_size); // uses filter_size
|
||||
this->doGaussBlur(); // uses filter_size, filter_sigma
|
||||
this->doGradiants();
|
||||
this->doGradiantMagnitude();
|
||||
// TODO: Checkpoint for 'before t_low changed'
|
||||
|
@ -651,11 +651,12 @@ void ImageViewer::applyBasicFilterWithOverflowHandling() {
|
||||
void ImageViewer::runCannyEdge(void) {
|
||||
CannyEdgeMachine cem = CannyEdgeMachine(original, working_copy);
|
||||
int filter_size = gauss_filter_size->value();
|
||||
double filter_sigma = gauss_filter_sigma->value();
|
||||
double t_low = t_low_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();
|
||||
cem.setGaussFilterSize(filter_size);
|
||||
cem.setGaussFilterParams(filter_size, filter_sigma);
|
||||
cem.setThresholdValues(t_low, t_high);
|
||||
cem.work();
|
||||
updateImageDisplay();
|
||||
@ -929,6 +930,10 @@ void ImageViewer::generateControlPanels() {
|
||||
gauss_filter_size->setMinimum(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->setDecimals(5);
|
||||
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(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(t_low_spinbox);
|
||||
task_tab5_scrolllayout->addWidget(new QLabel("High threshold value"));
|
||||
|
@ -148,6 +148,7 @@ class ImageViewer : public QMainWindow {
|
||||
QVBoxLayout* task_tab5_scrolllayout;
|
||||
|
||||
QDoubleSpinBox* gauss_filter_size;
|
||||
QDoubleSpinBox* gauss_filter_sigma;
|
||||
QDoubleSpinBox* t_low_spinbox;
|
||||
QDoubleSpinBox* t_high_spinbox;
|
||||
QPushButton* run_canny_edge;
|
||||
|
Loading…
Reference in New Issue
Block a user