使用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[] = {
  31. 0x42, // identity : B
  32. 0x4d, // identity : M
  33. , , , , // file size
  34. , , // reserved1
  35. , , // reserved2
  36. , , , , // RGB data offset
  37. , , , , // struct BITMAPINFOHEADER size
  38. , , , , // bmp width
  39. , , , , // bmp height
  40. , , // planes
  41. , , // bit per pixel
  42. , , , , // compression
  43. , , , , // data size
  44. , , , , // h resolution
  45. , , , , // v resolution
  46. , , , , // used colors
  47. , , , // important colors
  48. };
  49.  
  50. // sobel mask
  51. int mask[MASK_N][MASK_X][MASK_Y] = {
  52. {{-,-,-},
  53. { , , },
  54. { , , }},
  55.  
  56. {{-, , },
  57. {-, , },
  58. {-, , }}
  59. };
  60.  
  61. int read_bmp(const char *fname_s) {
  62. fp_s = fopen(fname_s, "rb");
  63. if (fp_s == NULL) {
  64. printf("fopen fp_s error\n");
  65. return -;
  66. }
  67.  
  68. // move offset to 10 to find rgb raw data offset
  69. fseek(fp_s, , SEEK_SET);
  70. fread(&rgb_raw_data_offset, sizeof(unsigned int), , fp_s);
  71.  
  72. // move offset to 18 to get width & height;
  73. fseek(fp_s, , SEEK_SET);
  74. fread(&width, sizeof(unsigned int), , fp_s);
  75. fread(&height, sizeof(unsigned int), , fp_s);
  76.  
  77. // get bit per pixel
  78. fseek(fp_s, , SEEK_SET);
  79. fread(&bit_per_pixel, sizeof(unsigned short), , fp_s);
  80. byte_per_pixel = bit_per_pixel / ;
  81.  
  82. // move offset to rgb_raw_data_offset to get RGB raw data
  83. fseek(fp_s, rgb_raw_data_offset, SEEK_SET);
  84.  
  85. image_s = (unsigned char *)malloc((size_t)width * height * byte_per_pixel);
  86. if (image_s == NULL) {
  87. printf("malloc images_s error\n");
  88. return -;
  89. }
  90.  
  91. image_t = (unsigned char *)malloc((size_t)width * height * byte_per_pixel);
  92. if (image_t == NULL) {
  93. printf("malloc image_t error\n");
  94. return -;
  95. }
  96.  
  97. fread(image_s, sizeof(unsigned char), (size_t)(long)width * height * byte_per_pixel, fp_s);
  98.  
  99. return ;
  100. }
  101.  
  102. // convert RGB to gray level int
  103. int color_to_int(int r, int g, int b) {
  104. return (r + g + b) / ;
  105. }
  106.  
  107. int sobel(double threshold) {
  108. unsigned int x, y, i, v, u; // for loop counter
  109. unsigned char R, G, B; // color of R, G, B
  110. double val[MASK_N] = {0.0};
  111. int adjustX, adjustY, xBound, yBound;
  112. double total;
  113.  
  114. for(y = ; y != height; ++y) {
  115. for(x = ; x != width; ++x) {
  116. for(i = ; i != MASK_N; ++i) {
  117. adjustX = (MASK_X % ) ? : ;
  118. adjustY = (MASK_Y % ) ? : ;
  119. xBound = MASK_X / ;
  120. yBound = MASK_Y / ;
  121.  
  122. val[i] = 0.0;
  123. for(v = -yBound; v != yBound + adjustY; ++v) {
  124. for (u = -xBound; u != xBound + adjustX; ++u) {
  125. if (x + u >= && x + u < width && y + v >= && y + v < height) {
  126. R = *(image_s + byte_per_pixel * (width * (y+v) + (x+u)) + );
  127. G = *(image_s + byte_per_pixel * (width * (y+v) + (x+u)) + );
  128. B = *(image_s + byte_per_pixel * (width * (y+v) + (x+u)) + );
  129.  
  130. val[i] += color_to_int(R, G, B) * mask[i][u + xBound][v + yBound];
  131. }
  132. }
  133. }
  134. }
  135.  
  136. total = 0.0;
  137. for (i = ; i != MASK_N; ++i) {
  138. total += val[i] * val[i];
  139. }
  140.  
  141. total = sqrt(total);
  142.  
  143. if (total - threshold >= ) {
  144. // black
  145. *(image_t + byte_per_pixel * (width * y + x) + ) = BLACK;
  146. *(image_t + byte_per_pixel * (width * y + x) + ) = BLACK;
  147. *(image_t + byte_per_pixel * (width * y + x) + ) = BLACK;
  148. }
  149. else {
  150. // white
  151. *(image_t + byte_per_pixel * (width * y + x) + ) = WHITE;
  152. *(image_t + byte_per_pixel * (width * y + x) + ) = WHITE;
  153. *(image_t + byte_per_pixel * (width * y + x) + ) = WHITE;
  154. }
  155. }
  156. }
  157.  
  158. return ;
  159. }
  160.  
  161. int write_bmp(const char *fname_t) {
  162. unsigned int file_size; // file size
  163.  
  164. fp_t = fopen(fname_t, "wb");
  165. if (fp_t == NULL) {
  166. printf("fopen fname_t error\n");
  167. return -;
  168. }
  169.  
  170. // file size
  171. file_size = width * height * byte_per_pixel + rgb_raw_data_offset;
  172. header[] = (unsigned char)(file_size & 0x000000ff);
  173. header[] = (file_size >> ) & 0x000000ff;
  174. header[] = (file_size >> ) & 0x000000ff;
  175. header[] = (file_size >> ) & 0x000000ff;
  176.  
  177. // width
  178. header[] = width & 0x000000ff;
  179. header[] = (width >> ) & 0x000000ff;
  180. header[] = (width >> ) & 0x000000ff;
  181. header[] = (width >> ) & 0x000000ff;
  182.  
  183. // height
  184. header[] = height &0x000000ff;
  185. header[] = (height >> ) & 0x000000ff;
  186. header[] = (height >> ) & 0x000000ff;
  187. header[] = (height >> ) & 0x000000ff;
  188.  
  189. // bit per pixel
  190. header[] = bit_per_pixel;
  191.  
  192. // write header
  193. fwrite(header, sizeof(unsigned char), rgb_raw_data_offset, fp_t);
  194.  
  195. // write image
  196. fwrite(image_t, sizeof(unsigned char), (size_t)(long)width * height * byte_per_pixel, fp_t);
  197.  
  198. fclose(fp_s);
  199. fclose(fp_t);
  200.  
  201. return ;
  202. }
  203.  
  204. int main() {
  205. read_bmp("lena.bmp"); // 24 bit gray level image
  206. sobel(90.0);
  207. write_bmp("lena_sobel.bmp");
  208. }
  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 = ;
  17. const int MASK_X = ;
  18. const int MASK_Y = ;
  19.  
  20. // Convert RGB to gray level int
  21. int colorToInt(Color %color) {
  22. return (color.R + color.G + color.B) / ;
  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 = ; y != oriImg->Height; ++y) {
  29. for(int x = ; x != oriImg->Width; ++x) {
  30. for(int i = ; i != MASK_N; ++i) {
  31. int adjustX = (MASK_X % ) ? : ;
  32. int adjustY = (MASK_Y % ) ? : ;
  33. int xBound = MASK_X / ;
  34. int yBound = MASK_Y / ;
  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 >= && x + u < oriImg->Width && y + v >= && 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 = ; i != MASK_N; ++i) {
  48. total += val[i] * val[i];
  49. }
  50.  
  51. total = sqrt(total);
  52.  
  53. if (total - threshold >= )
  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. {{-,-,-},
  64. { , , },
  65. { , , }},
  66.  
  67. {{-, , },
  68. {-, , },
  69. {-, , }}
  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 ;
  81. }

每天进步一点点------如何实现Sobel Edge Detector? (Image Processing) (C/C++)的更多相关文章

  1. Canny Edge Detector

    Canny边缘检测算法有自己的理论和经验性的推导, 没仔细看/没看明白. 它的步骤如下: 对原图的灰度图进行高斯滤波 求一阶导数, 得到每个像素点的梯度强度和方向. 非最大抑制. 对每个edge ca ...

  2. Understanding Convolution in Deep Learning

    Understanding Convolution in Deep Learning Convolution is probably the most important concept in dee ...

  3. 32个最热CPLD-FPGA论坛

    1. OPENCORES.ORG这里提供非常多,非常好的PLD了内核,8051内核就可以在里面找到.进入后,选择project或者由http//www.opencores.org/browse.cgi ...

  4. [转]FPGA网站推荐

    1. OPENCORES.ORG这里提供非常多,非常好的PLD了内核,8051内核就可以在里面找到.进入后,选择project或者由http//www.opencores.org/browse.cgi ...

  5. Computer Vision_33_SIFT:Remote Sensing Image Registration With Modified SIFT and Enhanced Feature Matching——2017

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

  6. OpenCV2马拉松第14圈——边缘检測(Sobel,prewitt,roberts)

    收入囊中 差分在边缘检測的角色 Sobel算子 OpenCV sobel函数 OpenCV Scharr函数 prewitt算子 Roberts算子 葵花宝典 差分在边缘检測究竟有什么用呢?先看以下的 ...

  7. Sobel Derivatives

    https://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html ...

  8. 线特征---Edge Drawing(七)

    http://ceng.anadolu.edu.tr/cv/edgedrawing/ References C. Topal, C. Akinlar, Edge Drawing: A Combined ...

  9. 2.7 Sobel导数

    OpenCV函数 Sobel(src_gray,grad_x/grad_y,ddepth,x_order,y_order,scale,delta,BORDER_DEFAULT ) Scharr( ) ...

随机推荐

  1. C++——指针2-指向数组的指针和指针数组

    7.4 指向数组元素的指针 声明与赋值 例:int a[10], *pa; pa=&a[0]; 或 pa=a[p1] ; 通过指针引用数组元素,经过上述声明及赋值后: *pa就是a[0],*( ...

  2. python特性

    # for用法 for i in range(0,100,2): print(i) n = 0 # while用法 while n < 100: print(n) n += 2 else: pr ...

  3. mybatis-plus - buildSqlSessionFactory()

    一. buildSqlSessionFactory() mybatis-plus 同样的是调用  factory.getObject() 方法来进行 SqlSessionFactory 创建的. 然后 ...

  4. 保存数据到文件的模块(json,pickle,shelve,configparser,xml)_python

    一.各模块的主要功能区别 json模块:将数据对象从内存中完成序列化存储,但是不能对函数和类进行序列化,写入的格式是明文.  (与其他大多语言交互的类型) pickle模块:将数据对象从内存中完成序列 ...

  5. nginx下载,安装,基础命令,和代理tomcat例子理解

    nginx代理讲的很好理解:https://www.cnblogs.com/ysocean/p/9392908.html 一.nginx应用场景: 1.反向代理(用的非常多) 客户端发出请求,反向代理 ...

  6. 【HTML】三种方法使HTML单页面输入密码才能访问

    方法一 <script type="text/javascript"> function password() { var testV = 1; var pass1 = ...

  7. MyEclipse 安装 emmet 插件

    1.在线安装 地址:http://download.emmet.io/eclipse/updates/ 安装完成后重新启动myeclipse 2.离线安装 下载jar包:https://github. ...

  8. IntelliJ IDEA快捷键设置

      IntelliJ IDEA是java编程语言开发的集成环境,目前有很多用户喜欢使用IDEA进行相关开发,IDEA使用起来十分方便,本篇博客主要是介绍IDEA快捷键(Keymap)的设置和使用. I ...

  9. c# 泛型<T>类型参数T的约束where

    在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制.如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误.这些限制称为约束.约束是使用 where 上 ...

  10. js设计模式之实现观察者模式实例代码

    前端界面 html代码 <body> <select name="" id="select"> <option value=&qu ...