每天进步一点点------如何实现Sobel Edge Detector? (Image Processing) (C/C++)

使用C與C++/CLI實現Sobel Edge Detector。

http://www.cnblogs.com/oomusou/archive/2008/07/23/sobel_edge_detector.html

  1 /* 
  2 (C) OOMusou 2007 http://oomusou.cnblogs.com
  3 
  4 Filename    : sobel_edge.c
  5 Compiler    : Visual C++ 8.0
  6 Description : Demo the how to use sobel detector on gray level image
  7 Release     : 07/23/2008 1.0
  8 */
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <math.h>
 12 
 13 #define MASK_N 2
 14 #define MASK_X 3
 15 #define MASK_Y 3
 16 #define WHITE  255
 17 #define BLACK  0
 18 
 19 unsigned char *image_s = NULL;     // source image array
 20 unsigned char *image_t = NULL;     // target image array
 21 FILE *fp_s = NULL;                 // source file handler
 22 FILE *fp_t = NULL;                 // target file handler
 23 
 24 unsigned int   width, height;      // image width, image height
 25 unsigned int   rgb_raw_data_offset;// RGB raw data offset
 26 unsigned char  bit_per_pixel;      // bit per pixel
 27 unsigned short byte_per_pixel;     // byte per pixel
 28 
 29 // bitmap header
 30 unsigned char header[54] = {
 31   0x42,        // identity : B
 32   0x4d,        // identity : M
 33   0, 0, 0, 0,  // file size
 34   0, 0,        // reserved1
 35   0, 0,        // reserved2
 36   54, 0, 0, 0, // RGB data offset
 37   40, 0, 0, 0, // struct BITMAPINFOHEADER size
 38   0, 0, 0, 0,  // bmp width
 39   0, 0, 0, 0,  // bmp height
 40   1, 0,        // planes
 41   24, 0,       // bit per pixel
 42   0, 0, 0, 0,  // compression
 43   0, 0, 0, 0,  // data size
 44   0, 0, 0, 0,  // h resolution
 45   0, 0, 0, 0,  // v resolution 
 46   0, 0, 0, 0,  // used colors
 47   0, 0, 0, 0   // important colors
 48 };
 49 
 50 
 51 // sobel mask
 52 int mask[MASK_N][MASK_X][MASK_Y] = {
 53   {{-1,-2,-1},
 54    {0 , 0, 0},
 55    {1 , 2, 1}},
 56 
 57   {{-1, 0, 1},
 58    {-2, 0, 2},
 59    {-1, 0, 1}}
 60 };
 61 
 62 int read_bmp(const char *fname_s) {
 63   fp_s = fopen(fname_s, "rb");
 64   if (fp_s == NULL) {
 65     printf("fopen fp_s error
");
 66     return -1;
 67   }
 68   
 69   // move offset to 10 to find rgb raw data offset
 70   fseek(fp_s, 10, SEEK_SET);
 71   fread(&rgb_raw_data_offset, sizeof(unsigned int), 1, fp_s);
 72   
 73   // move offset to 18 to get width & height;
 74   fseek(fp_s, 18, SEEK_SET); 
 75   fread(&width,  sizeof(unsigned int), 1, fp_s);
 76   fread(&height, sizeof(unsigned int), 1, fp_s);
 77   
 78   // get bit per pixel
 79   fseek(fp_s, 28, SEEK_SET); 
 80   fread(&bit_per_pixel, sizeof(unsigned short), 1, fp_s);
 81   byte_per_pixel = bit_per_pixel / 8;
 82   
 83   // move offset to rgb_raw_data_offset to get RGB raw data
 84   fseek(fp_s, rgb_raw_data_offset, SEEK_SET);
 85       
 86   image_s = (unsigned char *)malloc((size_t)width * height * byte_per_pixel);
 87   if (image_s == NULL) {
 88     printf("malloc images_s error
");
 89     return -1;
 90   }
 91     
 92   image_t = (unsigned char *)malloc((size_t)width * height * byte_per_pixel);
 93   if (image_t == NULL) {
 94     printf("malloc image_t error
");
 95     return -1;
 96   }
 97     
 98   fread(image_s, sizeof(unsigned char), (size_t)(long)width * height * byte_per_pixel, fp_s);
 99   
100   return 0;
101 }
102 
103 // convert RGB to gray level int
104 int color_to_int(int r, int g, int b) {
105   return (r + g + b) / 3;
106 }
107 
108 int sobel(double threshold) {
109   unsigned int  x, y, i, v, u;             // for loop counter
110   unsigned char R, G, B;         // color of R, G, B
111   double val[MASK_N] = {0.0};
112   int adjustX, adjustY, xBound, yBound;
113   double total;
114 
115   for(y = 0; y != height; ++y) {
116     for(x = 0; x != width; ++x) { 
117       for(i = 0; i != MASK_N; ++i) {
118         adjustX = (MASK_X % 2) ? 1 : 0;
119                 adjustY = (MASK_Y % 2) ? 1 : 0;
120                 xBound = MASK_X / 2;
121                 yBound = MASK_Y / 2;
122             
123         val[i] = 0.0;
124         for(v = -yBound; v != yBound + adjustY; ++v) {
125                     for (u = -xBound; u != xBound + adjustX; ++u) {
126             if (x + u >= 0 && x + u < width && y + v >= 0 && y + v < height) {
127               R = *(image_s + byte_per_pixel * (width * (y+v) + (x+u)) + 2);
128               G = *(image_s + byte_per_pixel * (width * (y+v) + (x+u)) + 1);
129               B = *(image_s + byte_per_pixel * (width * (y+v) + (x+u)) + 0);
130               
131                   val[i] +=    color_to_int(R, G, B) * mask[i][u + xBound][v + yBound];
132             }
133                     }
134         }
135       }
136 
137       total = 0.0;
138       for (i = 0; i != MASK_N; ++i) {
139               total += val[i] * val[i];
140       }
141 
142           total = sqrt(total);
143           
144       if (total - threshold >= 0) {
145         // black
146         *(image_t + byte_per_pixel * (width * y + x) + 2) = BLACK;
147         *(image_t + byte_per_pixel * (width * y + x) + 1) = BLACK;
148         *(image_t + byte_per_pixel * (width * y + x) + 0) = BLACK;
149       }
150             else {
151               // white
152         *(image_t + byte_per_pixel * (width * y + x) + 2) = WHITE;
153         *(image_t + byte_per_pixel * (width * y + x) + 1) = WHITE;
154         *(image_t + byte_per_pixel * (width * y + x) + 0) = WHITE;
155       }
156     }
157   }
158   
159   return 0;
160 }
161 
162 int write_bmp(const char *fname_t) {
163   unsigned int file_size; // file size
164   
165   fp_t = fopen(fname_t, "wb");
166   if (fp_t == NULL) {
167     printf("fopen fname_t error
");
168     return -1;
169   }
170        
171   // file size  
172   file_size = width * height * byte_per_pixel + rgb_raw_data_offset;
173   header[2] = (unsigned char)(file_size & 0x000000ff);
174   header[3] = (file_size >> 8)  & 0x000000ff;
175   header[4] = (file_size >> 16) & 0x000000ff;
176   header[5] = (file_size >> 24) & 0x000000ff;
177      
178   // width
179   header[18] = width & 0x000000ff;
180   header[19] = (width >> 8)  & 0x000000ff;
181   header[20] = (width >> 16) & 0x000000ff;
182   header[21] = (width >> 24) & 0x000000ff;
183      
184   // height
185   header[22] = height &0x000000ff;
186   header[23] = (height >> 8)  & 0x000000ff;
187   header[24] = (height >> 16) & 0x000000ff;
188   header[25] = (height >> 24) & 0x000000ff;
189      
190   // bit per pixel
191   header[28] = bit_per_pixel;
192    
193   // write header
194   fwrite(header, sizeof(unsigned char), rgb_raw_data_offset, fp_t);
195   
196   // write image
197   fwrite(image_t, sizeof(unsigned char), (size_t)(long)width * height * byte_per_pixel, fp_t);
198      
199   fclose(fp_s);
200   fclose(fp_t);
201      
202   return 0;
203 }
204   
205 int main() {
206   read_bmp("lena.bmp"); // 24 bit gray level image
207   sobel(90.0);
208   write_bmp("lena_sobel.bmp");
209 }
 1 /* 
 2 (C) OOMusou 2007 http://oomusou.cnblogs.com
 3 
 4 Filename    : sobel_edge.cpp
 5 Compiler    : C++/CLI / Visual C++ 8.0
 6 Description : Demo the how to use sobel detector on gray level image
 7 Release     : 07/23/2008 1.0
 8 */
 9 
10 #include "stdafx.h"
11 #include <cmath>
12 
13 using namespace System::Drawing;
14 using namespace System::Drawing::Imaging;
15 
16 const int MASK_N = 2;
17 const int MASK_X = 3;
18 const int MASK_Y = 3;
19 
20 // Convert RGB to gray level int
21 int colorToInt(Color %color) {
22   return (color.R + color.G + color.B) / 3;
23 }
24 
25 void edgeDetector(Bitmap^ oriImg, Bitmap^ resImg, const int mask[MASK_N][MASK_X][MASK_Y], const double &threshold) {
26   double val[MASK_N] = {0.0};
27 
28   for(int y = 0; y != oriImg->Height; ++y) {
29     for(int x = 0; x != oriImg->Width; ++x) { 
30       for(int i = 0; i != MASK_N; ++i) {
31         int adjustX = (MASK_X % 2) ? 1 : 0;
32                 int adjustY = (MASK_Y % 2) ? 1 : 0;
33                 int xBound = MASK_X / 2;
34                 int yBound = MASK_Y / 2;
35             
36         val[i] = 0.0;
37         for(int v = -yBound; v != yBound + adjustY; ++v) {
38                     for (int u = -xBound; u != xBound + adjustX; ++u) {
39             if (x + u >= 0 && x + u < oriImg->Width && y + v >= 0 && y + v < oriImg->Height) {
40                           val[i] +=    colorToInt(oriImg->GetPixel(x + u, y + v)) * mask[i][u + xBound][v + yBound];
41             }
42                     }
43         }
44       }
45 
46       double total = 0.0;
47       for (int i = 0; i != MASK_N; ++i) {
48               total += val[i] * val[i];
49       }
50 
51           total = sqrt(total);
52 
53       if (total - threshold >= 0) 
54         resImg->SetPixel(x , y, Color::Black);
55             else
56         resImg->SetPixel(x, y, Color::White);
57     }
58   }
59 }
60 
61 int main() {
62   const int mask[MASK_N][MASK_X][MASK_Y] = {
63               {{-1,-2,-1},
64               {0 , 0, 0},
65               {1 , 2, 1}},
66 
67               {{-1, 0, 1},
68               {-2, 0, 2},
69               {-1, 0, 1}}
70   };
71 
72   Bitmap^ oriImg = gcnew Bitmap("lena.bmp");
73   Bitmap^ resImg = gcnew Bitmap(oriImg->Width, oriImg->Height);
74 
75   const double threshold = 90.0;
76   edgeDetector(oriImg, resImg, mask, threshold);
77 
78   resImg->Save("lena_sobel.bmp");
79   
80   return 0;
81 }
原文地址:https://www.cnblogs.com/kongqiweiliang/p/3245490.html