java提取红色分量_提取图像里面的红色灯笼(一)

本文介绍了如何使用Java在RGB和HSI颜色空间中提取图像中的红色元素,如红色灯笼。通过设置阈值并应用膨胀、腐蚀等图像处理技术,有效地分离出红色目标并减少噪点。
摘要由CSDN通过智能技术生成

ec9661d2129c74c8c81e82cf253d23b7.png

图像的分割:RGB空间图像的分割:

/**************************************************************

函数功能:对图像rgb空间红色灯笼的提取

输入参数:源图像src;目标图像des;图像参数width,height,nChannels;

输出参数:目标图像

**************************************************************/

void rgb_seg(unsigned char* des, const unsigned char* src, int width, int height, int nChannels)

{

printf("%d,%d,%d,",nChannels,width,height);

unsigned char* ocl = new unsigned char[width * height * nChannels];

for(int y = 0; y < height; y++)

{

for(int x = 0; x < width; x++)

{

int img_B= src[y * width * nChannels + x * nChannels ] ;

int img_G= src[y * width * nChannels + x * nChannels + 1] ;

int img_R= src[y * width * nChannels + x * nChannels + 2] ;

if((img_R>140)&&(img_G<70)&&(img_B<70)) //简单的阈值提取

for(int n=0;n

des[y * width * nChannels + x * nChannels + n] = src[y * width * nChannels + x * nChannels + n] ;

else

for(int n=0;n

des[y * width * nChannels + x * nChannels + n] =255;

}

}

ImageDilation(ocl, des, width, height, nChannels,7);//用7*7的模板进行膨胀

ImageErosion(des, ocl, width, height, nChannels,13); //用13*13的模板进行腐蚀

ImageDilation(ocl, des, width, height, nChannels,13);//用13*13的模板进行膨胀

ImageReturn(des,ocl,src, width, height, nChannels,10);//用10*10的模板还原灯笼

}

下图第一幅为简单的红色分量阈值分割,第二幅为对前一副图像7*7的模板的膨胀。

e9e78710577a1f97b531fae6af84657b.png29a6ff84480fcbdb95d907d8536ea880.png

下图第一幅为用13*13的模板进行腐蚀,第二幅用13*13的模板再次进行膨胀:

234bee9e98635042deeb3ae48616b3c8.pngd2dad24e97c64192b5e525b4fe653f31.png

可见再次膨胀后的图像消除了所有的噪点,我们对这幅图像进行还原,还原的基本原理就是对图像有红色区域的部分用源图像进行相对应位置的填充。如下所示,对比原图可见其较好的找出了灯笼的轮廓。

109d5aca6456c6e5ba401cd2dad1fdf9.png9534818598e053ff65e0be7f9f531e93.png

图像的分割:HSI空间图像的分割:

/**************************************************************

函数功能:对图像hsi空间红色灯笼的提取

输入参数:源图像src;目标图像des;图像参数width,height,nChannels;

输出参数:目标图像

**************************************************************/

void hsi_seg(unsigned char* des, const unsigned char* src, int width, int height, int nChannels)

{

printf("%d,%d,%d,",nChannels,width,height);

unsigned char* ocl = new unsigned char[width * height * nChannels];

unsigned char* hsi = new unsigned char[width * height * nChannels];

rgb_hsi(hsi,src, width, height, nChannels); //hsi分量提取

for(int y = 0; y < height; y++)

{

for(int x = 0; x < width; x++)

{

int img_H= hsi[y * width * nChannels + x * nChannels ] ;

int img_S= hsi[y * width * nChannels + x * nChannels + 1] ;

int img_I= hsi[y * width * nChannels + x * nChannels + 2] ;

if(((img_H<104)&&(img_H>102))&&(img_I>40)&&(img_S>160))

{

//printf("%d, ",img_S);

for(int n=0;n

des[y * width * nChannels + x * nChannels + n] = src[y * width * nChannels + x * nChannels + n] ;

}

else

for(int n=0;n

des[y * width * nChannels + x * nChannels + n] =255;

}

}

ImageErosion(ocl, des, width, height, nChannels,2); //进行2*2的模板腐蚀

ImageDilation(des, ocl, width, height, nChannels,18);//进行18*18的模板膨胀

memcpy(ocl, des, nChannels*width*height);

ImageReturn(des,ocl,src, width, height, nChannels,10);//进行10*10的模板还原

}

下图第一幅图像为HIS空间对图像进行的简单的阈值分割,分割条件:

((img_H<104)&&(img_H>102))&&(img_I>40)&&(img_S>160)

可见其噪点很少,对其进行2*2的模板腐蚀再进行18*18的模板膨胀,如下右图所示:

e4456d74519dbba1b7866ea7ccc00767.pnga9f8698cd0e584d54e4e3c1bc07a1fe4.png

可见右图已经比较好的找出了灯笼的位置,我们用进行10*10的模板还原得到下面的图,和原图比较,也得到了比较好的效果。

e4e07d1140eeef7e4ad787c92a1bf5e6.pngca57af907a833a8b62ac516821fafb5c.png

下面是图像腐蚀、膨胀、还原的代码:

/**************************************************************

函数功能:对图像进行M*M模板的腐蚀

输入参数:源图像src;目标图像des;图像参数width,height,nChannels;腐蚀边长M

输出参数:目标图像

**************************************************************/

void ImageErosion(unsigned char* des, const unsigned char* src, int width, int height, int nChannels,int M)

{

memcpy(des, src, nChannels*width*height);

int m,p,k=0,q=0;

for(int y = 20; y < height-20; y++)

{

for(int x = 20; x < width-20; x++)

{

if((src[y * width * nChannels + x * nChannels + 2]!=255))

{

k=k+1;

for(m=-M;m<=M;m++)

{

for(p=-M;p<=M;p++)

{

if((src[(y+m) * width * nChannels + (x+p) * nChannels + 2])==255)

{

for(int n=0;n

des[y * width * nChannels + x * nChannels + n]=255;

}

}

}

}

else

{

q=q+1;

}

}

}

//printf("E%d %d",k,q);

}

/**************************************************************

函数功能:对图像进行M*M模板的膨胀

输入参数:源图像src;目标图像des;图像参数width,height,nChannels;膨胀边长M

输出参数:目标图像

**************************************************************/

void ImageDilation(unsigned char* des, const unsigned char* src, int width, int height,int nChannels,int M)

{

int m,p,k=0,q=0;

memcpy(des, src, nChannels*width*height);

for(int y = 20; y < height-20; y++)

{

for(int x = 20; x < width-20; x++)

{

if((src[y * width * nChannels + x * nChannels + 2]!=255))

{

k=k+1;

for(m=-M;m<=M;m++)

{

for(p=-M;p<=M;p++)

{

for(int n=0;n

des[(y+m) * width * nChannels + (x+p) * nChannels + n]=src[y * width * nChannels + x * nChannels + n];

}

}

}

else

{

q=q+1;

}

}

}

//printf("D%d %d",k,q);

}

/**************************************************************

函数功能:对图像进行M*M模板的原图像还原

输入参数:源图像src;目标图像des;图像参数width,height,nChannels;还原边长M

输出参数:目标图像

**************************************************************/

void ImageReturn(unsigned char* des, const unsigned char* ocl, const unsigned char* src, int width, int height, int nChannels,int M)

{

memcpy(des, ocl, nChannels*width*height);

int m,p,k=0,q=0;

for(int y = 30; y < height-30; y++)

{

for(int x = 30; x < width-30; x++)

{

if((ocl[y * width * nChannels + x * nChannels + 2]!=255))

{

k=k+1;

for(m=-M;m<=M;m++)

{

for(p=-M;p<=M;p++)

{

int B= src[(y+m) * width * nChannels + (x+p) * nChannels ] ;

int G= src[(y+m) * width * nChannels + (x+p) * nChannels + 1] ;

int R= src[(y+m) * width * nChannels + (x+p) * nChannels + 2] ;

if(R>130)

{

for(int n=0;n

des[(y+m) * width * nChannels + (x+p) * nChannels + n]=src[(y+m) * width * nChannels + (x+p) * nChannels + n];

//将还原区域用源图像进行填充

}

}

}

}

}

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值