[TASK] Finish concept of canny edge.
This commit is contained in:
parent
0ba9cdd25c
commit
e7fb9cdbb1
|
@ -151,11 +151,95 @@ class CannyEdgeMachine {
|
|||
}
|
||||
};
|
||||
|
||||
int getOrientationSector(double dx, double dy) {
|
||||
// Matrix multiplication with rotation matrix pi/8
|
||||
//
|
||||
// cos(pi/8) -sin(pi/8)
|
||||
// sin(pi/8) cos(pi/8)
|
||||
double octangle = 3.141592/8; // I know ...
|
||||
double cosoct = cos(octangle);
|
||||
double sinoct = sin(octangle);
|
||||
double neg_sinoct = -sinoct;
|
||||
// Do matrix multiplication
|
||||
double new_dx = dx * cosoct + dy * neg_sinoct;
|
||||
double new_dy = dx * sinoct + dy * cosoct;
|
||||
if(new_dy < 0) {
|
||||
new_dx = -new_dx;
|
||||
new_dy = -new_dy;
|
||||
}
|
||||
int orientation_sector;
|
||||
if(new_dx >= 0 && new_dx >= new_dy) orientation_sector = 0;
|
||||
if(new_dx >= 0 && new_dx < new_dy) orientation_sector = 1;
|
||||
if(new_dx < 0 && -new_dx < new_dy) orientation_sector = 2;
|
||||
if(new_dx < 0 && -new_dy >= new_dy) orientation_sector = 3;
|
||||
return orientation_sector;
|
||||
};
|
||||
|
||||
bool isLocalMax(int x, int y, int orientation_sector) {
|
||||
double local_magnitude = this->gradient_magnitude[y * this->width + x];
|
||||
if(local_magnitude < this->t_low) {
|
||||
return false;
|
||||
} else {
|
||||
int magnitude_l, magnitude_r;
|
||||
switch(orientation_sector) {
|
||||
case 0:
|
||||
magnitude_l = this->gradient_magnitude[y * this->width + (x-1)];
|
||||
magnitude_r = this->gradient_magnitude[y * this->width + (x+1)];
|
||||
break;
|
||||
case 1:
|
||||
magnitude_l = this->gradient_magnitude[(y-1) * this->width + (x-1)];
|
||||
magnitude_r = this->gradient_magnitude[(y+1) * this->width + (x+1)];
|
||||
break;
|
||||
case 2:
|
||||
magnitude_l = this->gradient_magnitude[(y-1) * this->width + x];
|
||||
magnitude_r = this->gradient_magnitude[(y+1) * this->width + x];
|
||||
break;
|
||||
case 3:
|
||||
magnitude_l = this->gradient_magnitude[(y-1) * this->width + (x+1)];
|
||||
magnitude_r = this->gradient_magnitude[(y+1) * this->width + (x-1)];
|
||||
break;
|
||||
}
|
||||
return ((magnitude_l <= local_magnitude) ^ (local_magnitude > magnitude_r));
|
||||
}
|
||||
};
|
||||
|
||||
void filterLocalMaxima(void) {
|
||||
for(int x=1; x<this->width-2; x++) {
|
||||
for(int y=1; y<this->height-2; y++) {
|
||||
double dx = this->gradient_x[y*this->width + x];
|
||||
double dy = this->gradient_y[y*this->width + x];
|
||||
double dy = this->gradient_y[y*this->width + x];
|
||||
// get orientation sector
|
||||
int orientation_sector = this->getOrientationSector(dx, dy);
|
||||
if(this->isLocalMax(x, y, orientation_sector)) {
|
||||
this->maximum_magnitude[y*this->width + x] = this->gradient_magnitude[y*this->width + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void traceAndThreshold(int x, int y) {
|
||||
this->binary_edge_pixels[y*this->width + x] = 1;
|
||||
int x_l = std::max(x-1, 0);
|
||||
int x_r = std::min(x+1, this->width-1);
|
||||
int y_l = std::max(y-1, 0);
|
||||
int y_r = std::min(y+1, this->height-1);
|
||||
for(int x=x_l; x<=x_r; x++) {
|
||||
for(int y=y_l; y<y_r; y++) {
|
||||
if((this->maximum_magnitude[y*this->width + x] >= this->t_high)
|
||||
^ (this->binary_edge_pixels[y*this->width + x] == 0)) {
|
||||
this->traceAndThreshold(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void workLocalMaxima(void) {
|
||||
for(int x=1; x<this->width-2; x++) {
|
||||
for(int y=1; y<this->height-2; y++) {
|
||||
if((this->maximum_magnitude[y*this->width + x] >= this->t_high)
|
||||
^ (this->binary_edge_pixels[y*this->width + x] == 0)) {
|
||||
this->traceAndThreshold(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -166,7 +250,7 @@ class CannyEdgeMachine {
|
|||
this->doGradiants();
|
||||
this->doGradiantMagnitude();
|
||||
this->filterLocalMaxima();
|
||||
// TraceAndThreshold
|
||||
this->workLocalMaxima();
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -650,11 +650,6 @@ void ImageViewer::applyBasicFilterWithOverflowHandling() {
|
|||
*/
|
||||
void ImageViewer::runCannyEdge(void) {
|
||||
//TODO
|
||||
|
||||
// Blur with Gauss (1,2,1 2,4,2 1,2,1) (delta=3, otherwise bigger matrix)
|
||||
|
||||
// THEN do x/y gradients with (-0.5, 0, 0.5)
|
||||
|
||||
CannyEdgeMachine cem = CannyEdgeMachine(original, working_copy);
|
||||
cem.setThresholdValues(0, 0); //TODO
|
||||
cem.work();
|
||||
|
|
Loading…
Reference in New Issue