c语言实现图像2d卷积运算,【数字图像处理】图像形态学算法C语言实现(图像卷积,膨胀,腐蚀,开运算,闭运算,顶帽,黑帽,雕版,锐化)...

/*

* @Descripttion:

* @version:

* @Author: Yueyang

* @email: 1700695611@qq.com

* @Date: 2020-11-10 21:59:39

* @LastEditors: Yueyang

* @LastEditTime: 2020-11-24 21:15:30

*/

#ifndef LI_CONV_C

#define LI_CONV_C

#include "cv.h"

#include "li_image_proc.h"

#include

/**

* @name: Li_GetKernel

* @msg: 获得卷积核矩阵

* @param {double* data 数据

* BYTE KernalKind 卷积核边长}

* @return {Li_Kernel*}

*/

LI_API

Li_Kernel* Li_GetKernel(double* data,BYTE KernalKind)

{

Li_Kernel * kernel;

kernel=(Li_Kernel*)li_malloc_arr(sizeof(Li_Kernel));

kernel->arr=(double*)li_malloc_arr(KernalKind*KernalKind*sizeof(double));

for(int i=0;i

kernel->arr[i]=data[i];

kernel->width=KernalKind;

kernel->height=KernalKind;

kernel->arrsize=KernalKind*KernalKind;

return kernel;

}

/**

* @name: Li_Convolute

* @msg: 计算图像卷积

* @param {Li_Image* img 卷积图像

* Li_Kernel* kernal 卷积核 }

* @return {Li_Image*}

*/

LI_API

Li_Image* Li_Convolute(Li_Image* img,Li_Kernel* kernal)

{

if(img->imgdepth==LI_DEP_8U){

if(kernal->width!=3) return NULL;

BYTE* ptr[9]={0};

BYTE* ptro;

Li_Image* out=Li_Copy_Image(img);

for(int i=0;iheight;i++)

for(int j=0;jwidth;j++)

{

BYTE sum=0;

if(j-1>=0&&i-1>=0)

ptr[0]=(BYTE*)img->at(img,j-1,i-1);

if(j>=0&&i-1>=0)

ptr[1]=(BYTE*)img->at(img,j+0,i-1);

if(j+1<=img->width&&i-1>=0)

ptr[2]=(BYTE*)img->at(img,j+1,i-1);

if(j-1>=0&&i>=0)

ptr[3]=(BYTE*)img->at(img,j-1,i+0);

if(j>=0&&i>=0)

ptr[4]=(BYTE*)img->at(img,j+0,i+0);

if(j+1<=img->width&&i>=0)

ptr[5]=(BYTE*)img->at(img,j+1,i+0);

if(j-1>=0&&i+1<=img->height)

ptr[6]=(BYTE*)img->at(img,j-1,i+1);

if(j>=0&&i+1<=img->height)

ptr[7]=(BYTE*)img->at(img,j+0,i+1);

if(j+1<=img->width&&i+1<=img->height)

ptr[8]=(BYTE*)img->at(img,j+1,i+1);

for(int k=0;k<9;k++)

{

double* ptr2=(double*)(kernal->arr+k);

if(ptr[k]!=NULL)

{

sum+= (BYTE)(*ptr[k] * (*ptr2));

}

else

{

sum+=0;

}

}

ptro=(BYTE*)out->at(out,j+0,i+0);

*ptro=sum;

}

return out;

}else if (img->imgdepth==LI_DEP_24U||img->imgdepth==LI_DEP_32U)

{

Li_Image* imgH[img->imgdepth+1];

Li_Image* imgL[img->imgdepth+1];

Li_Split(img,imgH);

for(int i=0;iimgdepth+1;i++)

imgL[i]= Li_Convolute(imgH[i],kernal);

Li_Image* out2=Li_Combine(imgL,img->imgdepth);

return out2;

}

}

/**

* @name: Li_Sharp

* @msg: 图像锐化

* @param {Li_Image* img}

* @return {Li_Image*}

*/

LI_API

Li_Image* Li_Sharp(Li_Image* img)

{

double data[9]={1,1,1,1,-7,1,1,1,1};

if(img==NULL)return NULL;

if(img->imgdepth==LI_DEP_8U){

Li_Image* out;

Li_Kernel* kernel;

kernel=Li_GetKernel(data,3);

out= Li_Convolute(img,kernel);

return out;

}else if (img->imgdepth==LI_DEP_24U||img->imgdepth==LI_DEP_32U)

{

Li_Image* imgH[img->imgdepth+1];

Li_Image* imgL[img->imgdepth+1];

Li_Split(img,imgH);

for(int i=0;iimgdepth+1;i++)

{

imgL[i]=Li_Sharp(imgH[i]);

}

Li_Image* out2=Li_Combine(imgL,img->imgdepth);

return out2;

}

}

/**

* @name: Li_Emboss

* @msg: 图像雕版

* @param {Li_Image* img}

* @return {Li_Image*}

*/

LI_API

Li_Image* Li_Emboss(Li_Image* img)

{

double data[9]={0,0,-1,0,-1,0,2,0,0};

if(img==NULL)return NULL;

if(img->imgdepth==LI_DEP_8U){

Li_Image* out;

Li_Kernel* kernel;

kernel=Li_GetKernel(data,3);

out= Li_Convolute(img,kernel);

return out;

}else if (img->imgdepth==LI_DEP_24U||img->imgdepth==LI_DEP_32U)

{

Li_Image* imgH[img->imgdepth+1];

Li_Image* imgL[img->imgdepth+1];

Li_Split(img,imgH);

for(int i=0;iimgdepth+1;i++)

{

imgL[i]=Li_Emboss(imgH[i]);

}

Li_Image* out2=Li_Combine(imgL,img->imgdepth);

return out2;

}

}

/**

* @name: Li_Erode

* @msg: 图像腐蚀(局部最小)

* @param {Li_Image* img}

* @return {Li_Image*}

*/

LI_API

Li_Image* Li_Erode(Li_Image* img)

{

if(img->imgdepth==LI_DEP_8U){

BYTE kek=0;

BYTE* ptr[9]={0};

BYTE* ptro;

Li_Image* out=Li_Copy_Image(img);

for(int i=0;iheight;i++)

for(int j=0;jwidth;j++)

{

BYTE sum=0;

for(int k=0;k<9;k++)

ptr[k]=&kek;

if(j-1>=0&&i-1>=0)

ptr[0]=(BYTE*)img->at(img,j-1,i-1);

if(j>=0&&i-1>=0)

ptr[1]=(BYTE*)img->at(img,j+0,i-1);

if(j+1<=img->width&&i-1>=0)

ptr[2]=(BYTE*)img->at(img,j+1,i-1);

if(j-1>=0&&i>=0)

ptr[3]=(BYTE*)img->at(img,j-1,i+0);

if(j>=0&&i>=0)

ptr[4]=(BYTE*)img->at(img,j+0,i+0);

if(j+1<=img->width&&i>=0)

ptr[5]=(BYTE*)img->at(img,j+1,i+0);

if(j-1>=0&&i+1<=img->height)

ptr[6]=(BYTE*)img->at(img,j-1,i+1);

if(j>=0&&i+1<=img->height)

ptr[7]=(BYTE*)img->at(img,j+0,i+1);

if(j+1<=img->width&&i+1<=img->height)

ptr[8]=(BYTE*)img->at(img,j+1,i+1);

BYTE temp[9];

for(int k=0;k<9;k++)

{

if(ptr[k]!=NULL)

{

temp[k]= (BYTE)(*ptr[k]);

}

}

for(int m=0;m<9-1;m++)

for(int n=0;n<9-m-1;n++)

{

if(temp[m]>temp[m+1])

{

BYTE x=temp[m];

temp[m]=temp[n+1];

temp[n+1]=x;

}

}

ptro=(BYTE*)out->at(out,j+0,i+0);

*ptro=temp[0];

}

return out;

}else if (img->imgdepth==LI_DEP_24U||img->imgdepth==LI_DEP_32U)

{

Li_Image* imgH[img->imgdepth+1];

Li_Image* imgL[img->imgdepth+1];

Li_Split(img,imgH);

for(int i=0;iimgdepth+1;i++)

imgL[i]= Li_Medeum(imgH[i]);

Li_Image* out2=Li_Combine(imgL,img->imgdepth);

return out2;

}

}

/**

* @name: Li_Dilate

* @msg: 图像膨胀(局部最小)

* @param {Li_Image* img}

* @return {Li_Image*}

*/

LI_API

Li_Image* Li_Dilate(Li_Image* img)

{

if(img->imgdepth==LI_DEP_8U){

BYTE kek=0;

BYTE* ptr[9]={0};

BYTE* ptro;

Li_Image* out=Li_Copy_Image(img);

for(int i=0;iheight;i++)

for(int j=0;jwidth;j++)

{

BYTE sum=0;

for(int k=0;k<9;k++)

ptr[k]=&kek;

if(j-1>=0&&i-1>=0)

ptr[0]=(BYTE*)img->at(img,j-1,i-1);

if(j>=0&&i-1>=0)

ptr[1]=(BYTE*)img->at(img,j+0,i-1);

if(j+1<=img->width&&i-1>=0)

ptr[2]=(BYTE*)img->at(img,j+1,i-1);

if(j-1>=0&&i>=0)

ptr[3]=(BYTE*)img->at(img,j-1,i+0);

if(j>=0&&i>=0)

ptr[4]=(BYTE*)img->at(img,j+0,i+0);

if(j+1<=img->width&&i>=0)

ptr[5]=(BYTE*)img->at(img,j+1,i+0);

if(j-1>=0&&i+1<=img->height)

ptr[6]=(BYTE*)img->at(img,j-1,i+1);

if(j>=0&&i+1<=img->height)

ptr[7]=(BYTE*)img->at(img,j+0,i+1);

if(j+1<=img->width&&i+1<=img->height)

ptr[8]=(BYTE*)img->at(img,j+1,i+1);

BYTE temp[9];

for(int k=0;k<9;k++)

{

if(ptr[k]!=NULL)

{

temp[k]= (BYTE)(*ptr[k]);

}

}

for(int m=0;m<9-1;m++)

for(int n=0;n<9-m-1;n++)

{

if(temp[m]>temp[m+1])

{

BYTE x=temp[m];

temp[m]=temp[n+1];

temp[n+1]=x;

}

}

ptro=(BYTE*)out->at(out,j+0,i+0);

*ptro=temp[8];

}

return out;

}else if (img->imgdepth==LI_DEP_24U||img->imgdepth==LI_DEP_32U)

{

Li_Image* imgH[img->imgdepth+1];

Li_Image* imgL[img->imgdepth+1];

Li_Split(img,imgH);

for(int i=0;iimgdepth+1;i++)

imgL[i]= Li_Medeum(imgH[i]);

Li_Image* out2=Li_Combine(imgL,img->imgdepth);

return out2;

}

}

/**

* @name: Li_Grandient

* @msg: 形态学梯度

* @param {Li_Image* img}

* @return {Li_Image*}

*/

LI_API

Li_Image* Li_Grandient(Li_Image* img)

{

Li_Image* erode=Li_Erode(img);

Li_Image* dilate=Li_Dilate(img);

Li_Image* minus=Li_Minus(dilate,erode);

Li_Destroy_Image(erode);

Li_Destroy_Image(dilate);

return minus;

}

/**

* @name: Li_Mod_Open

* @msg: 形态学开运算

* @param {Li_Image* img}

* @return {Li_Image* }

*/

LI_API

Li_Image* Li_Mod_Open(Li_Image* img)

{

Li_Image* dilate=Li_Dilate(img);//先膨胀

Li_Image* erode=Li_Erode(dilate);//先腐蚀

Li_Destroy_Image(dilate);

return erode;

}

/**

* @name: Li_Mod_Close

* @msg: 形态学闭运算

* @param {Li_Image* img}

* @return {Li_Image* }

*/

LI_API

Li_Image* Li_Mod_Close(Li_Image* img)

{

Li_Image* erode=Li_Erode(img);//先腐蚀

Li_Image* dilate=Li_Dilate(erode);//先膨胀

Li_Destroy_Image(erode);

return dilate;

}

/**

* @name: Li_TopHat

* @msg: 图像顶帽运算

* @param {Li_Image* img}

* @return {Li_Image*}

*/

LI_API

Li_Image* Li_TopHat(Li_Image* img)

{

Li_Image* open=Li_Mod_Open(img);

Li_Image* top=Li_Minus(img,open);

Li_Destroy_Image(open);

return top;

}

/**

* @name: Li_BlackHat

* @msg: 图像黑帽运算

* @param {Li_Image* img}

* @return {Li_Image*}

*/

LI_API

Li_Image* Li_BlackHat(Li_Image* img)

{

Li_Image* close=Li_Mod_Close(img);

Li_Image* black=Li_Minus(img,close);

Li_Destroy_Image(close);

return black;

}

#endif// !LI_CONV_C

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值