图片处理(四)之边沿检测
来源:互联网 发布:unity3d手机游戏 编辑:程序博客网 时间:2024/04/28 02:40
本代码主要工作是对图片的数据进行边沿检测。
检测边界这里会说两种方法,一种叫Laplacian边沿检测,另一种叫Sobel边沿检测,Laplacian计算量相对较少,Sobel边沿更清晰。
首先我们要有一个概念,当对图片的数据进行一次求导后,得到的是图片的色差变化速度,当对图片的数据进行二次求导后,得到的是图片色差变化速度的速度,即色差突变,当我们收集所有的色差突变数据,得到的就是图片的边沿。
Laplacian边沿检测:二次求导,直接对xy整合计算,得到:
@(@f )= f(x,y+1)+ f(x,y-1)+ f(x+1,y)+f(x-1,y)+ -4f(x,y) //@表示求导
即:
| 0 | 1 | 0 |
| 1 | -4 | 1 |
| 0 | 1 | 0 |
Sobel边沿检测:二次求导,x与y分开计算再整合,得到://@表示求导
@(@fx)=[f(x+1,y-1)+2f(x+1,y)+f(x+1,y+1)]-[f(x-1,y-1)+2f(x-1,y)+f(x-1,y+1)]
| -1 | 0 | 1 |
| -2 | 0 | 2 |
| -1 | 0 | 1 |
@(@fx)=[f(x-1,y-1)+2f(x,y-1)+f(x+1,y-1)]-[f(x-1,y+1)+2f(x,y+1)+f(x+1,y+1)]
| 1 | 2 | 1 |
| 0 | 0 | 0 |
| -1 | -2 | -1 |
为整合计算,直接取绝对值进行相加,获取边沿数据,得到:
@(@f )= Abs( @(@fx) )+abs( @(@fx) )
//GraphEdgeHandle1 Sobel边沿检测
//GraphEdgeHandle Laplacian边沿检测
实现代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define ADD 0
#define SUB 1
#define MUL 2
#define DIV 3
#define Y_ADD 0
#define Y_SUB 1
#define CUR_POS(x,y,width) ((y)*width+(x))
#define X_POS(pos) ((pos)%PicWidth)
#define Y_POS(pos) ((pos)/PicWidth)
#define RANGE(x) (x<0?0:(x>255?255:x))
//---------------picattribute----------------------
unsignedint PicWidth;
unsignedint PicHeight;
//--------------------------------------------------
voidGraphBrightHandle(unsigned char *src, unsigned char *dest, int size, int type,double num);
voidGraphLPFHandle(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height);
voidGraphEdgeHandle (unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height);
voidGraphEdgeHandle1(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height);
intmain(int argc,char** argv)
{
int nErrorCode=0;
FILE *fin;
FILE *fout_Bright;
FILE *fout_LPF;
FILE *fout_Edge;
char szInFilename[256];
char szOutFilename[256];
if(argc>=2)
{
strcpy(szInFilename ,argv[1]);
}
else
{
strcpy(szInFilename, "44.raw");
}
printf("src:%s\n",szInFilename);
if(argc>=4)
{
PicWidth = atoi(argv[2]);
PicHeight= atoi(argv[3]);
}
else
{
PicWidth = 640;
PicHeight= 480;
}
printf("PicWidth:%d,PicHeight:%d\n",PicWidth,PicHeight);
fin = fopen(szInFilename , "rb");
fout_Bright =fopen("GraphBright.raw" ,"wb");
fout_LPF = fopen("GraphLPF.raw" , "wb");
fout_Edge = fopen("GraphEdge.raw" , "wb");
if(fin && fout_Bright &&fout_LPF && fout_Edge)
{
//getthe input file size
unsignedint FileSize = 0;
fseek(fin,0, SEEK_END);
FileSize= ftell(fin);
fseek(fin,0, SEEK_SET);
printf("Filesize : %d\n", FileSize);
//geta memory
unsignedchar *DataBuf = (unsigned char *)malloc(FileSize);
memset(DataBuf,0, FileSize);
//readdata to DataBuf
if ( 0 == fread(DataBuf, FileSize, 1,fin) )
{
nErrorCode |= 0x4;
}
#if0 //Brignt Handle
GraphBrightHandle(DataBuf,DataBuf, FileSize, MUL, 1.5);
if( 0 == fwrite(DataBuf, FileSize, 1, fout_Bright) )
{
nErrorCode |= 0x8;
}
#endif
#if0 //LFP Handle
unsignedchar *DataBufLPF = (unsigned char *)malloc(FileSize);
memset(DataBufLPF,0, FileSize);
GraphLPFHandle(DataBuf,DataBufLPF, PicWidth, PicHeight);
if( 0 == fwrite(DataBufLPF, FileSize, 1, fout_LPF) )
{
nErrorCode |= 0x10;
}
#endif
#if1 //Edge check
unsignedchar *DataBufEdge = (unsigned char *)malloc(FileSize);
memset(DataBufEdge,0, FileSize);
GraphEdgeHandle1(DataBuf,DataBufEdge, PicWidth, PicHeight);
if( 0 == fwrite(DataBufEdge, FileSize, 1, fout_Edge) )
{
nErrorCode |= 0x11;
}
#endif
}
else
{
nErrorCode|= 0x01;
}
if(fin)
{
fclose(fin);
}
if(fout_Bright)
{
fclose(fout_Bright);
}
if(fout_LPF)
{
fclose(fout_LPF);
}
printf("nErrorCode: %d\n",nErrorCode);
system("pause");
return nErrorCode;
}
voidGraphBrightHandle(unsigned char *src, unsigned char *dest, int size, int type,double num)
{
int i = 0;
int R = 0, G = 0, B = 0;
for(i = 0; i < size; i+=3)
{
R= src[i+0];
G= src[i+1];
B= src[i+2];
switch(type)
{
case ADD: R += num; G += num; B += num; break;
case SUB: R -= num; G -= num; B -= num; break;
case MUL: R *= num; G *= num; B *= num; break;
case DIV: R /= num; G /= num; B /= num; break;
default: printf("no exist Brighttype\n"); break;
}
if(R< 0) R = 0;
if(G< 0) G = 0;
if(B< 0) B = 0;
if(R> 255) R = 255;
if(G> 255) G = 255;
if(B> 255) B = 255;
dest[i+0]= R;
dest[i+1]= G;
dest[i+2]= B;
}
}
voidGraphLPFHandle(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height)
{
unsigned int C, U, D, R, L;
int x, y;
double tmp;
for(y = 0; y < Height; y++)
{
for(x = 0; x < Width; x++)
{
C = CUR_POS(x,y,Width);
(0 == x)? (L = C):( L = y*Width + (x-1) );
(Width-1 == x)? (R = C):( R = y*Width + (x+1) );
(0 == y)? (U = C):( U = (y-1)*Width + x );
(Height-1 == y)? (D = C):( D =(y+1)*Width + x );
tmp =*(src+3*C+0)*0.5
+*(src+3*L+0)*0.125
+*(src+3*R+0)*0.125
+*(src+3*U+0)*0.125
+*(src+3*D+0)*0.125;
*(dest+3*C+0) = tmp;
tmp = *(src+3*C+1)*0.5
+*(src+3*L+1)*0.125
+*(src+3*R+1)*0.125
+*(src+3*U+1)*0.125
+*(src+3*D+1)*0.125;
*(dest+3*C+1) = tmp;
tmp = *(src+3*C+2)*0.5
+*(src+3*L+2)*0.125
+*(src+3*R+2)*0.125
+*(src+3*U+2)*0.125
+*(src+3*D+2)*0.125;
*(dest+3*C+2) = tmp;
}
}
}
voidGraphEdgeHandle1(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height)
{
int x, y;
int xA,xB,xC,xD,xE,xF;
int yA,yB,yC,yD,yE,yF;
int Sx,Sy,tmp;
for(y = 1; y < Height-1; y++)
{
for(x = 1; x < Width-1; x++)
{
xA = (y-1)*Width + (x-1);
xB = (y+0)*Width + (x-1);
xC = (y+1)*Width + (x-1);
xD = (y-1)*Width + (x+1);
xE = (y+0)*Width + (x+1);
xF = (y+1)*Width + (x+1);
yA = (y-1)*Width + (x-1);
yB = (y-1)*Width + (x+0);
yC = (y-1)*Width + (x+1);
yD = (y+1)*Width + (x-1);
yE = (y+1)*Width + (x+0);
yF = (y+1)*Width + (x+1);
//R
Sx =-*(src+3*xA+0)-*(src+3*xB+0)*2-*(src+3*xC+0)
+*(src+3*xD+0)+*(src+3*xE+0)*2+*(src+3*xF+0);
Sy =-*(src+3*yA+0)-*(src+3*yB+0)*2-*(src+3*yC+0)
+*(src+3*yD+0)+*(src+3*yE+0)*2+*(src+3*yF+0);
tmp = abs(Sx)+abs(Sy);
*(dest+3*CUR_POS(x,y,Width)+0) =RANGE(tmp);
//G
Sx =-*(src+3*xA+1)-*(src+3*xB+1)*2-*(src+3*xC+1)
+*(src+3*xD+1)+*(src+3*xE+1)*2+*(src+3*xF+1);
Sy =-*(src+3*yA+1)-*(src+3*yB+1)*2-*(src+3*yC+1)
+*(src+3*yD+1)+*(src+3*yE+1)*2+*(src+3*yF+1);
tmp = abs(Sx)+abs(Sy);
*(dest+3*CUR_POS(x,y,Width)+1) =RANGE(tmp);
//B
Sx =-*(src+3*xA+2)-*(src+3*xB+2)*2-*(src+3*xC+2)
+*(src+3*xD+2)+*(src+3*xE+2)*2+*(src+3*xF+2);
Sy =-*(src+3*yA+2)-*(src+3*yB+2)*2-*(src+3*yC+2)
+*(src+3*yD+2)+*(src+3*yE+2)*2+*(src+3*yF+2);
tmp = abs(Sx)+abs(Sy);
*(dest+3*CUR_POS(x,y,Width)+2) =RANGE(tmp);
}
}
}
voidGraphEdgeHandle(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height)
{
unsigned int C, U, D, R, L;
int x, y, tmp;
for(y = 0; y < Height; y++)
{
for(x = 0; x < Width; x++)
{
C = CUR_POS(x,y,Width);
(0 == x)? (L = C):( L = y*Width + (x-1) );
(Width-1 == x)? (R = C):( R = y*Width + (x+1) );
(0 == y)? (U = C):( U = (y-1)*Width + x );
(Height-1 == y)? (D = C):( D =(y+1)*Width + x );
tmp =*(src+3*C+0)*(-4)
+*(src+3*L+0)*1
+*(src+3*R+0)*1
+*(src+3*U+0)*1
+*(src+3*D+0)*1;
if(tmp < 0) tmp = 0;
if(tmp > 255) tmp = 255;
*(dest+3*C+0) = tmp;
tmp = *(src+3*C+1)*(-4)
+*(src+3*L+1)*1
+*(src+3*R+1)*1
+*(src+3*U+1)*1
+*(src+3*D+1)*1;
if(tmp < 0) tmp = 0;
if(tmp > 255) tmp = 255;
*(dest+3*C+1) = tmp;
tmp = *(src+3*C+2)*(-4)
+*(src+3*L+2)*1
+*(src+3*R+2)*1
+*(src+3*U+2)*1
+*(src+3*D+2)*1;
if(tmp < 0) tmp = 0;
if(tmp > 255) tmp = 255;
*(dest+3*C+2) = tmp;
}
}
}
- 图片处理(四)之边沿检测
- 边沿检测(转)
- 边沿检测(转)
- FPGA 学习之路(五)边沿检测技术
- 脉冲边沿检测(Verilog)
- 边沿检测电路(一)
- 边沿检测电路(二)
- 脉冲边沿检测的亚稳态处理
- 边沿检测
- 边沿检测
- 在android平台上利用opencv进行图像处理之边沿检测
- 边沿检测法之彻底理解
- FPGA学习之边沿检测电路
- 图像处理--边沿检测与提取,轮廓跟踪
- FPGA基础之脉冲边沿检测原理verilog版本
- FPGA的边沿检测
- 边沿检测技术
- FPGA的边沿检测
- C 二维数组的动态申请与释放
- 栈练习之C语言中实现中缀转后缀表达式
- 设计模式之代理模式
- C++容器的insert()函数有以下三种用法: 最终*it=val;
- Linux使用curl访问https站点时报错汇总
- 图片处理(四)之边沿检测
- UITextView限制最大输入长度(UITextField相同)
- ttyS0 as tty in kernel
- kafka producer consumer 实时读数据
- Android官方开发文档Training系列课程中文版:多样屏幕之实现自适应UI
- Android数据加密之MD5
- log4j:WARN No appenders could be found for logger
- STL sort()函数详解
- 实现模拟自动化来操作桌面