每天进步一点点------如何实现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
/*
(C) OOMusou 2007 http://oomusou.cnblogs.com Filename : sobel_edge.c
Compiler : Visual C++ 8.0
Description : Demo the how to use sobel detector on gray level image
Release : 07/23/2008 1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h> #define MASK_N 2
#define MASK_X 3
#define MASK_Y 3
#define WHITE 255
#define BLACK 0 unsigned char *image_s = NULL; // source image array
unsigned char *image_t = NULL; // target image array
FILE *fp_s = NULL; // source file handler
FILE *fp_t = NULL; // target file handler unsigned int width, height; // image width, image height
unsigned int rgb_raw_data_offset;// RGB raw data offset
unsigned char bit_per_pixel; // bit per pixel
unsigned short byte_per_pixel; // byte per pixel // bitmap header
unsigned char header[] = {
0x42, // identity : B
0x4d, // identity : M
, , , , // file size
, , // reserved1
, , // reserved2
, , , , // RGB data offset
, , , , // struct BITMAPINFOHEADER size
, , , , // bmp width
, , , , // bmp height
, , // planes
, , // bit per pixel
, , , , // compression
, , , , // data size
, , , , // h resolution
, , , , // v resolution
, , , , // used colors
, , , // important colors
}; // sobel mask
int mask[MASK_N][MASK_X][MASK_Y] = {
{{-,-,-},
{ , , },
{ , , }}, {{-, , },
{-, , },
{-, , }}
}; int read_bmp(const char *fname_s) {
fp_s = fopen(fname_s, "rb");
if (fp_s == NULL) {
printf("fopen fp_s error\n");
return -;
} // move offset to 10 to find rgb raw data offset
fseek(fp_s, , SEEK_SET);
fread(&rgb_raw_data_offset, sizeof(unsigned int), , fp_s); // move offset to 18 to get width & height;
fseek(fp_s, , SEEK_SET);
fread(&width, sizeof(unsigned int), , fp_s);
fread(&height, sizeof(unsigned int), , fp_s); // get bit per pixel
fseek(fp_s, , SEEK_SET);
fread(&bit_per_pixel, sizeof(unsigned short), , fp_s);
byte_per_pixel = bit_per_pixel / ; // move offset to rgb_raw_data_offset to get RGB raw data
fseek(fp_s, rgb_raw_data_offset, SEEK_SET); image_s = (unsigned char *)malloc((size_t)width * height * byte_per_pixel);
if (image_s == NULL) {
printf("malloc images_s error\n");
return -;
} image_t = (unsigned char *)malloc((size_t)width * height * byte_per_pixel);
if (image_t == NULL) {
printf("malloc image_t error\n");
return -;
} fread(image_s, sizeof(unsigned char), (size_t)(long)width * height * byte_per_pixel, fp_s); return ;
} // convert RGB to gray level int
int color_to_int(int r, int g, int b) {
return (r + g + b) / ;
} int sobel(double threshold) {
unsigned int x, y, i, v, u; // for loop counter
unsigned char R, G, B; // color of R, G, B
double val[MASK_N] = {0.0};
int adjustX, adjustY, xBound, yBound;
double total; for(y = ; y != height; ++y) {
for(x = ; x != width; ++x) {
for(i = ; i != MASK_N; ++i) {
adjustX = (MASK_X % ) ? : ;
adjustY = (MASK_Y % ) ? : ;
xBound = MASK_X / ;
yBound = MASK_Y / ; val[i] = 0.0;
for(v = -yBound; v != yBound + adjustY; ++v) {
for (u = -xBound; u != xBound + adjustX; ++u) {
if (x + u >= && x + u < width && y + v >= && y + v < height) {
R = *(image_s + byte_per_pixel * (width * (y+v) + (x+u)) + );
G = *(image_s + byte_per_pixel * (width * (y+v) + (x+u)) + );
B = *(image_s + byte_per_pixel * (width * (y+v) + (x+u)) + ); val[i] += color_to_int(R, G, B) * mask[i][u + xBound][v + yBound];
}
}
}
} total = 0.0;
for (i = ; i != MASK_N; ++i) {
total += val[i] * val[i];
} total = sqrt(total); if (total - threshold >= ) {
// black
*(image_t + byte_per_pixel * (width * y + x) + ) = BLACK;
*(image_t + byte_per_pixel * (width * y + x) + ) = BLACK;
*(image_t + byte_per_pixel * (width * y + x) + ) = BLACK;
}
else {
// white
*(image_t + byte_per_pixel * (width * y + x) + ) = WHITE;
*(image_t + byte_per_pixel * (width * y + x) + ) = WHITE;
*(image_t + byte_per_pixel * (width * y + x) + ) = WHITE;
}
}
} return ;
} int write_bmp(const char *fname_t) {
unsigned int file_size; // file size fp_t = fopen(fname_t, "wb");
if (fp_t == NULL) {
printf("fopen fname_t error\n");
return -;
} // file size
file_size = width * height * byte_per_pixel + rgb_raw_data_offset;
header[] = (unsigned char)(file_size & 0x000000ff);
header[] = (file_size >> ) & 0x000000ff;
header[] = (file_size >> ) & 0x000000ff;
header[] = (file_size >> ) & 0x000000ff; // width
header[] = width & 0x000000ff;
header[] = (width >> ) & 0x000000ff;
header[] = (width >> ) & 0x000000ff;
header[] = (width >> ) & 0x000000ff; // height
header[] = height &0x000000ff;
header[] = (height >> ) & 0x000000ff;
header[] = (height >> ) & 0x000000ff;
header[] = (height >> ) & 0x000000ff; // bit per pixel
header[] = bit_per_pixel; // write header
fwrite(header, sizeof(unsigned char), rgb_raw_data_offset, fp_t); // write image
fwrite(image_t, sizeof(unsigned char), (size_t)(long)width * height * byte_per_pixel, fp_t); fclose(fp_s);
fclose(fp_t); return ;
} int main() {
read_bmp("lena.bmp"); // 24 bit gray level image
sobel(90.0);
write_bmp("lena_sobel.bmp");
}
/*
(C) OOMusou 2007 http://oomusou.cnblogs.com Filename : sobel_edge.cpp
Compiler : C++/CLI / Visual C++ 8.0
Description : Demo the how to use sobel detector on gray level image
Release : 07/23/2008 1.0
*/ #include "stdafx.h"
#include <cmath> using namespace System::Drawing;
using namespace System::Drawing::Imaging; const int MASK_N = ;
const int MASK_X = ;
const int MASK_Y = ; // Convert RGB to gray level int
int colorToInt(Color %color) {
return (color.R + color.G + color.B) / ;
} void edgeDetector(Bitmap^ oriImg, Bitmap^ resImg, const int mask[MASK_N][MASK_X][MASK_Y], const double &threshold) {
double val[MASK_N] = {0.0}; for(int y = ; y != oriImg->Height; ++y) {
for(int x = ; x != oriImg->Width; ++x) {
for(int i = ; i != MASK_N; ++i) {
int adjustX = (MASK_X % ) ? : ;
int adjustY = (MASK_Y % ) ? : ;
int xBound = MASK_X / ;
int yBound = MASK_Y / ; val[i] = 0.0;
for(int v = -yBound; v != yBound + adjustY; ++v) {
for (int u = -xBound; u != xBound + adjustX; ++u) {
if (x + u >= && x + u < oriImg->Width && y + v >= && y + v < oriImg->Height) {
val[i] += colorToInt(oriImg->GetPixel(x + u, y + v)) * mask[i][u + xBound][v + yBound];
}
}
}
} double total = 0.0;
for (int i = ; i != MASK_N; ++i) {
total += val[i] * val[i];
} total = sqrt(total); if (total - threshold >= )
resImg->SetPixel(x , y, Color::Black);
else
resImg->SetPixel(x, y, Color::White);
}
}
} int main() {
const int mask[MASK_N][MASK_X][MASK_Y] = {
{{-,-,-},
{ , , },
{ , , }}, {{-, , },
{-, , },
{-, , }}
}; Bitmap^ oriImg = gcnew Bitmap("lena.bmp");
Bitmap^ resImg = gcnew Bitmap(oriImg->Width, oriImg->Height); const double threshold = 90.0;
edgeDetector(oriImg, resImg, mask, threshold); resImg->Save("lena_sobel.bmp"); return ;
}
每天进步一点点------如何实现Sobel Edge Detector? (Image Processing) (C/C++)的更多相关文章
- Canny Edge Detector
Canny边缘检测算法有自己的理论和经验性的推导, 没仔细看/没看明白. 它的步骤如下: 对原图的灰度图进行高斯滤波 求一阶导数, 得到每个像素点的梯度强度和方向. 非最大抑制. 对每个edge ca ...
- Understanding Convolution in Deep Learning
Understanding Convolution in Deep Learning Convolution is probably the most important concept in dee ...
- 32个最热CPLD-FPGA论坛
1. OPENCORES.ORG这里提供非常多,非常好的PLD了内核,8051内核就可以在里面找到.进入后,选择project或者由http//www.opencores.org/browse.cgi ...
- [转]FPGA网站推荐
1. OPENCORES.ORG这里提供非常多,非常好的PLD了内核,8051内核就可以在里面找到.进入后,选择project或者由http//www.opencores.org/browse.cgi ...
- Computer Vision_33_SIFT:Remote Sensing Image Registration With Modified SIFT and Enhanced Feature Matching——2017
此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...
- OpenCV2马拉松第14圈——边缘检測(Sobel,prewitt,roberts)
收入囊中 差分在边缘检測的角色 Sobel算子 OpenCV sobel函数 OpenCV Scharr函数 prewitt算子 Roberts算子 葵花宝典 差分在边缘检測究竟有什么用呢?先看以下的 ...
- Sobel Derivatives
https://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html ...
- 线特征---Edge Drawing(七)
http://ceng.anadolu.edu.tr/cv/edgedrawing/ References C. Topal, C. Akinlar, Edge Drawing: A Combined ...
- 2.7 Sobel导数
OpenCV函数 Sobel(src_gray,grad_x/grad_y,ddepth,x_order,y_order,scale,delta,BORDER_DEFAULT ) Scharr( ) ...
随机推荐
- [CF2B] The least round way - dp
给定由非负整数组成的n×n 的正方形矩阵,你需要寻找一条路径: 以左上角为起点 每次只能向右或向下走 以右下角为终点 并且,如果我们把沿路遇到的数进行相乘,积应当是最小"round" ...
- JVM学习-环境构建
想学习JVM,java虚拟机的底层原理.下面介绍下怎么将Java文件compiler成字节码,然后反编译为二进制查看分析. 一.JavaClass.java文件: package com.gqz.ja ...
- appium+android测试环境安装
1. jdk配置 一.背景 JDK已经更新到12了,但是由于很多工具仍然未及时更新,故推荐最稳定的JDK版本1.8.x: JDK需要配置通常情况下,JDK配置分为三项: JAVA_HOME:某些软件仍 ...
- python中可变类型和不可变类型数据的复制
常见的复制方式有以下5种第1种:通过等号[=]复制 - 不论可变还是不可变数据类型,通过[=]复制后都指向同一个内存地址: - 改变复制后的数据(例子中的anotherStr,anotherList) ...
- moveTo 与 moveBy的区别 (转贴)
MoveTo和MoveBy可以使精灵移动,区别在于MoveTo是移动到给定的坐标点:而MoveBy是从当前坐标点移动给定的坐标点这么多的距离.举个例子,假定精灵当前的坐标点是(x, y),分别给Mov ...
- itext操作表单域导出PDF,俗称扣模板
/** * templateUrl 模板文件路径,包含文件名 * targetUrl 目标路径 * dateMap 填充数据 */public class CreatePdfUtil { public ...
- 题解【洛谷P6029】[JSOI2010]旅行
题面 简化版题意:给出 \(n\) 个点 \(m\) 条边的无向图,可以交换任意两条边的权值 \(k\) 次,求 \(1\) 结点到 \(n\) 结点的最短路. 考虑\(\text{DP}\). 把所 ...
- 数据库ETL同步 cdc开启,Git同步url添加用户名密码
添加双主键 alter table TChargeRecordMainNew add constraint pk_name primary key (任务编码,序号) ---------------- ...
- Oracle VM VirtualBox - 启用 VT-x/AMD-V 支持
问题描述Oracle VM VirtualBox引入OVF模板时,报错:VT-x/AMD-V 硬件加速已被启用, 但当前处于无效状态. 您虚拟电脑内的操作系统将无法检测到64位的处理器,因此也将无法启 ...
- 在多租户(容器)数据库中如何创建PDB:方法3 克隆远程PDB
基于版本:19c (12.2.0.3) AskScuti 创建方法:克隆远程PDB(从非当前CDB中进行远程克隆).将 CDB2 中的 ERP1 远程克隆为 CDB1 中的 PDB6 对应路径:Cre ...