📄 处理..c
字号:
//小波部分的包含文件//
#include <stdio.h>
#include "alloc.h"
#include <math.h>
#include "macros.h"
#include "wav_filters_extern.h"
#include "wav_filters.h"
#include "wav_trf.h"
#include "wav_gen.h"
//图像部分的包含文件及定义//
#include <windows.h>
#include "image32.h"
extern HDC hMemDC;
extern struct IMAGE *image;
extern struct IMAGE *Image[10];
int Mask[3][3],Scale,Offset;
// 二值化定义部分//
long pg[256],pg1[256];
int T_gray[256],thre_v;
//canny边缘检测定义部分//
#define ORI_SCALE 40.0
#define MAX_MASK_SIZE 20
#define PI 3.14
float ratio = 0.1;
int WIDTH = 0;
#define MAG_SCALE 20.0
#define sigma 1.0
//函数声明//
void ColorToGray(int m,int n);
void addnoise(struct IMAGE *image,int x,int y,int Dx,int Dy);
float gauss2(float x,float y);
//canny部分函数声明//
void seperable_convolution (struct IMAGE *image, BYTE **list1,int Dx,int Dy,float *gau, int width,
float **smx, float **smy);
void dxy_seperable_convolution (float** im, int nr, int nc, float *gau,
int width, float **sm, int which);
float gauss(float x);
float dGauss (float x);
float norm (float x, float y);
void nonmax_suppress (float **dx, float **dy, int nr, int nc,
BYTE **list0, BYTE **list2);
void hysteresis (int high, int low, struct IMAGE *image,BYTE **list1,BYTE **list0, BYTE **list2);
void estimate_thresh (BYTE **list0, int *hi, int *low);
int trace (int i, int j, int low, struct IMAGE *image,BYTE **list1,BYTE **list0, BYTE **list2);
int range (struct IMAGE *image,BYTE **list0, int i, int j);
void loG(struct IMAGE *image,int x,int y,int Dx,int Dy);
//小波部分函数声明//
void wavelet(struct IMAGE *image,int x,int y,int Dx,int Dy);
void waveletinverse(struct IMAGE *image,int x,int y,int Dx,int Dy);
void wavelet_edge(struct IMAGE *image,int x,int y,int Dx,int Dy);
//图像象素与模板卷积函数//
void Template(BYTE **list1,BYTE **list0,int Dx,int Dy)
{
int i,j,g;
for (i=1;i<Dy-1;i++) {
for (j=1;j<Dx-1;j++) {
g = (Mask[0][0]*list1[i-1][j-1]+Mask[0][1]*list1[i-1][j]
+Mask[0][2]*list1[i-1][j+1]+Mask[1][0]*list1[i][j-1]
+Mask[1][1]*list1[i][j] +Mask[1][2]*list1[i][j+1]
+Mask[2][0]*list1[i+1][j-1]+Mask[2][1]*list1[i+1][j]
+Mask[2][2]*list1[i+1][j+1])/Scale+Offset;
if (g>0xff) g=0xff;
else if (g<0) g=0;
list0[i][j] = (BYTE) g;
}
}
}
void TemplateD(struct IMAGE *image,int x,int y,int Dx,int Dy)
{
BYTE *buf1,*buf0;
BYTE **list1,**list0;
int i;
buf1 =(BYTE*) malloc(Dx*Dy*sizeof(BYTE));
buf0 =(BYTE*) malloc(Dx*Dy*sizeof(BYTE));
getimage(image,x,y,Dx,Dy,buf1);
list1=(BYTE**) malloc(Dy*sizeof(BYTE*));
list0=(BYTE**) malloc(Dy*sizeof(BYTE*));
for(i=0;i<Dy;i++) {
list1[i]=buf1+i*Dx;
list0[i]=buf0+i*Dx;
}
Template(list1,list0,Dx,Dy);
for(i=1;i<Dy-1;i++)
setimage(image,x+1,y+i,Dx-2,1,&list0[i][1]);
free(buf1);
free(buf0);
free(list1);
free(list0);
}
//拉普拉死函数//
void LapSketchDE(struct IMAGE *image,int x,int y,int Dx,int Dy)
{
Scale=1; Offset=0;
Mask[0][0]=Mask[0][2]=Mask[2][0]=Mask[2][2]=-1;
Mask[0][1]=Mask[2][1]=Mask[1][0]=Mask[1][2]=-1;
Mask[1][1]=8;
TemplateD(image,x,y,Dx,Dy);
Offset=0;
}
//拉普拉死边缘检测.............................................//
void Ex(HWND hWnd)
{
if ((Image[0]->hdib==NULL)||(Image[0]->bitcount<8)) return;
ClearDDB();
WriteDDB(Image[0], 0, 0, 0, 0,512,512);
ColorToGray(0,1);
LapSketchDE(Image[1],0,0,Image[1]->wid,Image[1]->hei);
WriteDDB(Image[1],512, 0, 0, 0,512,512);
InvalidateRect(hWnd,NULL,FALSE);
}
//平滑函数//
void smooth(struct IMAGE *image,int x,int y,int Dx,int Dy)
{
Scale=10;
Mask[0][0]=Mask[0][2]=Mask[2][0]=Mask[2][2]=0;
Mask[0][1]=Mask[2][1]=Mask[1][0]=Mask[1][2]=1;
Mask[1][1]=1;
TemplateD(image,x,y,Dx,Dy);
Offset=0;
}
//平滑.........................................//
void EX4(HWND hWnd)
{
if ((Image[0]->hdib==NULL)||(Image[0]->bitcount<8)) return;
ClearDDB();
WriteDDB(Image[0], 0, 0, 0, 0,512,512);
ColorToGray(0,1);
smooth(Image[1],0,0,Image[1]->wid,Image[1]->hei);
WriteDDB(Image[1],512, 0, 0, 0,512,512);
InvalidateRect(hWnd,NULL,FALSE);
}
//sobel边缘检测程序//
void Sobel0(BYTE **list1,BYTE **list0,int Dx,int Dy,char ch)
{
int i,j,A,B,C;
for (i=1;i<Dy-1;i++) {
for (j=1;j<Dx-1;j++) {
A = abs((list1[i-1][j+1]+2*list1[i][j+1]+list1[i+1][j+1])-
(list1[i-1][j-1]+2*list1[i][j-1]+list1[i+1][j-1]));
B = abs((list1[i+1][j-1]+2*list1[i+1][j]+list1[i+1][j+1])-
(list1[i-1][j-1]+2*list1[i-1][j]+list1[i-1][j+1]));
switch(ch) {
case 'M' :
if (A>B) C = A;
else C = B;
break;
case 'H' :
C = A;
break;
case 'V' :
C = B;
break;
default :
break;
}
C /= Scale;
if (C>255) C=255;
list0[i][j] = C;
}
}
}
void SobelD0(struct IMAGE *image,int x,int y,int Dx,int Dy,char ch)
{
BYTE *buf1,*buf0;
BYTE **list1,**list0;
int i;
Scale=1; Offset=0;
buf1 =(BYTE*) malloc(Dx*Dy*sizeof(BYTE));
buf0 =(BYTE*) malloc(Dx*Dy*sizeof(BYTE));
getimage(image,x,y,Dx,Dy,buf1); // 数据读入输入图像
list1=(BYTE**) malloc(Dy*sizeof(BYTE*)); // 申请二维输入数组
list0=(BYTE**) malloc(Dy*sizeof(BYTE*)); // 申请二维输出数组
for(i=0;i<Dy;i++) {
list1[i]=buf1+i*Dx;
list0[i]=buf0+i*Dx;
}
Sobel0(list1,list0,Dx,Dy, ch);
for(i=1;i<Dy-1;i++)
// 显示结果
setimage(image,x+1,y+i,Dx-2,1,&list0[i][1]);
free(buf1);
free(buf0);
free(list1);
free(list0);
}
//sobel边缘检测...........................................//
void EX2(HWND hWnd)
{
if ((Image[0]->hdib==NULL)||(Image[0]->bitcount<8)) return;
ClearDDB();
WriteDDB(Image[0], 0, 0, 0, 0,512,512);
ColorToGray(0,1);
SobelD0(Image[1],0,0,Image[1]->wid,Image[1]->hei,'M');
WriteDDB(Image[1],512, 0, 0, 0,512,512);
InvalidateRect(hWnd,NULL,FALSE);
Offset=0;
}
//灰阶.........................................//
void EX3(HWND hWnd)
{
if ((Image[0]->hdib==NULL)||(Image[0]->bitcount<8)) return;
ClearDDB();
WriteDDB(Image[0], 0, 0, 0, 0,512,512);
ColorToGray(0,1);
WriteDDB(Image[1],512, 0, 0, 0,512,512);
InvalidateRect(hWnd,NULL,FALSE);
Offset=0;
}
// 统计直方图//
void histog(struct IMAGE *image,long *pg,int Xs, int Ys, int Dx, int Dy)
{
BYTE *sc;
int i,j;
sc=(BYTE*) malloc(Dx);
for (i=0;i<256;i++) pg[i]=0;
for(i=0;i<Dy;i++) {
getimage(image,Xs, Ys+i, Dx, 1, sc);
for (j=0;j<Dx;j++) pg[sc[j]]++;
}
free(sc);
}
//取阈值//
int Otsu(long *pg,long *pg1)
{
int i,j,p;
double A,B,An,Bn,u,v,qqq[256],max,min;
An=Bn=0;
for (i=0;i<256;i++) {
An+=pg[i]; Bn+=pg[i]*(i+1);
}
for (j=0;j<256;j++) {
A=B=0;
for (i=0;i<=j;i++) {
A+=pg[i]; B+=pg[i]*(i+1);
}
if (A) u=B/A;
else u=0;
if (An-A) v=(Bn-B)/(An-A);
else v=0;
qqq[j]=A*(An-A)*(u-v)*(u-v);
}
max=min=qqq[0]; p=0;
for (i=1;i<256;i++) {
if (qqq[i]>max) {
max=qqq[i];
p=i;
}
else if (qqq[i]<min) min=qqq[i];
}
if (pg1!=0) {
for (i=0;i<256;i++) {
pg1[i]=(long) (120*(qqq[i]-min)/(max-min));
}
}
return(p);
}
// 绘制直方图//
void draw_histog(long *pg,int x,int y,int h,int flag)
{
LOGPEN lppen = {PS_SOLID,1,1,RGB(255,0,0)};
DWORD Hist1[256];
int i,j,k,l,t;
HPEN hPen;
hMemDC=CreateMemDC();
for (j=0;j<256;j++) Hist1[j]=pg[j];
k=1;
for (j=0,k=1;j<200;j++) {
for (i=0,t=0;i<256;i++) {
if ((int)(Hist1[i]/k)<h) t++;
}
if (t>252) break;
k++;
}
for (i=0;i<256;i++) {
Hist1[i]/=k;
if ((int) Hist1[i]>h) Hist1[i]=h;
}
lppen.lopnColor=RGB(128,128,128);
hPen=SelectObject(hMemDC,CreatePenIndirect(&lppen));
MoveToEx(hMemDC,x,y,NULL);
LineTo(hMemDC,x+256,y);
DeleteObject(SelectObject(hMemDC,hPen));
lppen.lopnColor=RGB(0,0,0);
hPen=SelectObject(hMemDC,CreatePenIndirect(&lppen));
MoveToEx(hMemDC,x,y-Hist1[0],NULL);
for (i=0;i<256;i++) {
l=Hist1[i];
if (l>0) {
if (flag==0)
MoveToEx(hMemDC,x+i,y,NULL);
LineTo(hMemDC,x+i,y-l);
}
}
DeleteObject(SelectObject(hMemDC,hPen));
DeleteMemDC(hMemDC);
}
// 灰度变换--二值化 //
void Threshold_G(int *T_gray,int thre)
{
int i,w,b;
thre_v=thre;
b=0; w=255;
for (i=0;i<thre_v;i++) T_gray[i]=b;
for (i=thre_v;i<256;i++) T_gray[i]=w;
}
// 实现灰度变换//
void GT(struct IMAGE *image,int x,int y,int Dx,int Dy)
{
BYTE buf[2048];
int i,j;
for (i=0;i<Dy;i++) {
getimage(image,x,y+i,Dx,1,buf);
for (j=0;j<Dx;j++) {
buf[j]=T_gray[buf[j]]; // 查表
}
setimage(image,x,y+i,Dx,1,buf);
}
}
// 灰度变换--二值化 //
void GT_Threshold(struct IMAGE *image,int x,int y,int Dx,int Dy,int thre)
{
Threshold_G(T_gray,thre);
GT(image,x,y,Dx,Dy);
}
//图像二值化阈值分割...................................//
void EX5(HWND hWnd)
{
int t;
char StringT[20];
if ((Image[0]->hdib==NULL)||(Image[0]->bitcount<8)) return;
ClearDDB();
WriteDDB(Image[0], 0, 0, 0, 0,512,512);
ColorToGray(0,1);
histog(Image[1],pg,0,0,Image[1]->wid,Image[1]->hei);
t=Otsu(pg,pg1);
draw_histog(pg,128,650,125,0);
draw_histog(pg1,640,650,125,1);
hMemDC=CreateMemDC();
MoveToEx(hMemDC,128+t,655,NULL);
LineTo(hMemDC,128+t,670);
MoveToEx(hMemDC,640+t,655,NULL);
LineTo(hMemDC,640+t,670);
TextOut(hMemDC,470,600,"二值化阈值",10);
sprintf(StringT,"%5d",t);
TextOut(hMemDC,490,630,StringT,strlen(StringT));
DeleteMemDC(hMemDC);
GT_Threshold(Image[1],0,0,Image[1]->wid,Image[1]->hei,t);
WriteDDB(Image[1],512, 0, 0, 0,512,512);
InvalidateRect(hWnd,NULL,FALSE);
}
// 延时子程序,延时 n 毫秒//
void delay(int n)
{
DWORD StartTime,CurrentTime,m;
StartTime=GetTickCount();
do {
CurrentTime=GetTickCount();
m=(CurrentTime-StartTime);
}
while((int) m<n);
}
//加噪声.........................................//
void EX6(HWND hWnd)
{
if ((Image[0]->hdib==NULL)||(Image[0]->bitcount<8))
return;
ClearDDB();
WriteDDB(Image[0], 0, 0, 0, 0,512,512);
ColorToGray(0,1);
addnoise(Image[1],0,0,Image[1]->wid,Image[1]->hei);
WriteDDB(Image[1],512, 0, 0, 0,512,512);
InvalidateRect(hWnd,NULL,FALSE);
Offset=0;
}
//加噪声函数//
void addnoise(struct IMAGE *image,int x,int y,int Dx,int Dy)
{ BYTE *buf1,*buf0;
BYTE **list1,**list0;
int i,j;
float scale;
scale=1000;
buf1 =(BYTE*) malloc(Dx*Dy*sizeof(BYTE));
buf0 =(BYTE*) malloc(Dx*Dy*sizeof(BYTE));
getimage(image,x,y,Dx,Dy,buf1);
list1=(BYTE**) malloc(Dy*sizeof(BYTE*));
list0=(BYTE**) malloc(Dy*sizeof(BYTE*));
for(i=0;i<Dy;i++) {
list1[i]=buf1+i*Dx;
list0[i]=buf0+i*Dx;
}
for(i=0;i<Dx;i++)
for(j=0;j<Dy;j++)
{
list0[i][j]=list1[i][j]+(gauss2((float)(rand()/1000),(float)(rand()/1000))*scale);
}
for(i=0;i<Dx;i++)
for(j=0;j<Dy;j++)
{if(list0[i][j]>255) list0[i][j]=255;
else list0[i][j]=list0[i][j];
}
for(i=0;i<Dy-1;i++)
setimage(image,x+1,y+i,Dx-2,1,&list0[i][1]);
free(buf1);
free(buf0);
free(list1);
free(list0);
}
//二维gaussian 函数//
float gauss2(float x,float y)
{
float xx;
if (sigma == 0) return 0.0;
xx = (float)exp((double) (-(x*x+y*y)/(2*sigma*sigma)));
xx = xx/(PI*2.0*sigma*sigma);
return xx;
}
//prewitt函数//
void prewitt0(BYTE **list1,BYTE **list0,int Dx,int Dy,char ch)
{
int i,j,A,B,C;
for (i=1;i<Dy-1;i++) {
for (j=1;j<Dx-1;j++) {
A = abs((list1[i-1][j+1]+list1[i][j+1]+list1[i+1][j+1])-
(list1[i-1][j-1]+list1[i][j-1]+list1[i+1][j-1]));
B = abs((list1[i+1][j-1]+list1[i+1][j]+list1[i+1][j+1])-
(list1[i-1][j-1]+list1[i-1][j]+list1[i-1][j+1]));
switch(ch) {
case 'M' :
if (A>B) C = A;
else C = B;
break;
case 'H' :
C = A;
break;
case 'V' :
C = B;
break;
default :
break;
}
C /= Scale;
if (C>255) C=255;
list0[i][j] = C;
}
}
}
void prewittD0(struct IMAGE *image,int x,int y,int Dx,int Dy,char ch)
{
BYTE *buf1,*buf0;
BYTE **list1,**list0;
int i;
Scale=1; Offset=0;
buf1 =(BYTE*) malloc(Dx*Dy*sizeof(BYTE));
buf0 =(BYTE*) malloc(Dx*Dy*sizeof(BYTE));
getimage(image,x,y,Dx,Dy,buf1);
list1=(BYTE**) malloc(Dy*sizeof(BYTE*));
list0=(BYTE**) malloc(Dy*sizeof(BYTE*));
for(i=0;i<Dy;i++) {
list1[i]=buf1+i*Dx;
list0[i]=buf0+i*Dx;
}
prewitt0(list1,list0,Dx,Dy, ch);
for(i=1;i<Dy-1;i++)
setimage(image,x+1,y+i,Dx-2,1,&list0[i][1]);
free(buf1);
free(buf0);
free(list1);
free(list0);
}
//prewitt边缘检测.....................................//
void EX7(HWND hWnd)
{
if ((Image[0]->hdib==NULL)||(Image[0]->bitcount<8)) return;
ClearDDB();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -