• 每天进步一点点------如何实现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 }
  • 相关阅读:
    推荐大家看 《亵渎》
    vue 过滤器filters的使用以及常见报错小坑(Failed to resolve filter)
    vue 与原生app的对接交互(混合开发)
    vue 3.0使用 BUG解决
    202020211 20209313 《Linux内核原理与分析》第一周作业
    2第一周部分笔记
    Cartographer系列之二——hokuyo激光雷达跑cartographer
    ROS系列之初识gmapping
    Cartographer系列之一——初体验
    SLAM学习资料整理
  • 原文地址:https://www.cnblogs.com/kongqiweiliang/p/3245490.html
Copyright © 2020-2023  润新知