1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
#include "filter.h"
void canny(IplImage *src, IplImage *dst, int t_min, int t_max){
CvScalar p;
int rows = (src->height);
int cols = (src->width);
int ** gradient;
gradient = new int*[cols];
for (int i = 0; i < cols; i++)
{
gradient[i] = new int[rows];
for(int j=0;j<rows;j++){
gradient[i][j] = 0;
}
}
int ** theta;
theta = new int*[cols];
for (int i = 0; i < cols; i++)
{
theta[i] = new int[rows];
for(int j=0;j<rows;j++){
theta[i][j] = 0;
}
}
//Step 1 : Smoothing
gaussian(src,dst);
// Step 2 : Sobel Operator
int ** KX;
int ** KY;
// Kernel init
KX = new int*[3];
for (int i = 0; i < 3; i++)
{
KX[i] = new int[3];
for(int j=0;j<3;j++){
KX[i][j] = 0;
}
}
KX[0][0] = -1; KX[1][0] = -2; KX[2][0] = -1;
KX[0][2] = 1; KX[1][2] = 2; KX[2][2] = 1;
KY = new int*[3];
for (int i = 0; i < 3; i++)
{
KY[i] = new int[3];
for(int j=0;j<3;j++){
KY[i][j] = 0;
}
}
KY[0][0] = -1; KY[0][1] = -2; KY[0][2] = -1;
KY[2][0] = 1; KY[2][1] = 2; KY[2][2] = 1;
for(int i=0; i < rows; ++i) // rows
{
for(int j=0; j < cols ; ++j) // columns
{
int sumX = 0; // init to 0 before sum
int sumY = 0;
for(int m=0; m < 3; ++m) // kernel rows
{
int mm = 3 - 1 - m; // row index of flipped kernel
for(int n=0; n < 3; ++n) // kernel columns
{
int nn = 3 - 1 - n; // column index of flipped kernel
// index of input signal, used for checking boundary
int ii = i + (m - 1);
int jj = j + (n - 1);
// ignore input samples which are out of bound
if( ii >= 0 && ii < rows && jj >= 0 && jj < cols )
p = cvGet2D(src,jj,ii);
sumX += p.val[0]*KX[mm][nn];
sumY += p.val[0]*KY[mm][nn];
}
}
p.val[0] = abs(sumX) + abs(sumY);
// Step 3 : Non Maxima Suppression
gradient[i][j] = p.val[0];
float thisAngle;
int newAngle;
thisAngle = (atan2((double)sumY,(double)sumX)/3.14159)*180;
if ( ( (thisAngle < 22.5) && (thisAngle > -22.5) ) || (thisAngle > 157.5) || (thisAngle < -157.5) ){
newAngle = 0;
}
if ( ( (thisAngle > 22.5) && (thisAngle < 67.5) ) || ( (thisAngle < -112.5) && (thisAngle > -157.5) ) ){
newAngle = 45;
}
if ( ( (thisAngle > 67.5) && (thisAngle < 112.5) ) || ( (thisAngle < -67.5) && (thisAngle > -112.5) ) ){
newAngle = 90;
}
if ( ( (thisAngle > 112.5) && (thisAngle < 157.5) ) || ( (thisAngle < -22.5) && (thisAngle > -67.5) ) ){
newAngle = 135;
}
theta[i][j] = newAngle;
}
}
for(int i=1; i < rows-1; ++i)
{
for(int j=1; j < cols-1 ; ++j)
{
if(theta[i][j] == 0){
if(gradient[i][j] < gradient[i+1][j] && gradient[i][j] < gradient[i-1][j]){
gradient[i][j] = 0;
}
}
else if(theta[i][j] == 45){
if(gradient[i][j] < gradient[i+1][j+1] && gradient[i][j] < gradient[i-1][j-1]){
gradient[i][j] = 0;
}
}
else if(theta[i][j] == 90){
if(gradient[i][j] < gradient[i][j+1] && gradient[i][j] < gradient[i-1][j-1]){
gradient[i][j] = 0;
}
}
else if(theta[i][j] == 135){
if(gradient[i][j] < gradient[i+1][j-1] && gradient[i][j] < gradient[i-1][j+1]){
gradient[i][j] = 0;
}
}
p.val[0] = gradient[i][j];
cvSet2D(dst,j,i,p);
}
}
} |