问题描述:
将图片进行均值、中值、高斯滤波,高斯边缘检测,并在图片上添加中文文字。
一、算法思想
- 首先经过
opencv
的一系列操作,例如高斯模糊、均值模糊等操作后、用Imgcodecs.imwrite
方法将图片写出到指定的位置。 - 再利用
java
的图片添加文字的方法实现。 - 再读取输出。
二、代码解析
进行均值模糊
/**
* void blur(InputArray src, OutputArray dst, Size ksize,
* Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
* src:输入图像
* dst:输出图像
* ksize:均值滤波器模板大小
* anchor:锚点,如果为Point(-1,-1),则锚点是滤波器的中心点
* borderType:边缘点插值类型
* */
Imgproc.blur(src, gry, new Size(4, 4));
实现中值模糊
/**
* void medianBlur(InputArray src, OutputArray dst, int ksize)
* src:输入图像
* dst:输出图像
* ksize:均值滤波器模板大小,因为模板为正方形,所以只有一个参数。
* */
Imgproc.medianBlur(src,dst,5);
实现高斯滤波
/**
* void GaussianBlur(InputArray src, OutputArray dst, Size ksize,
* double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT ) ;
* src:输入图像
* dst:输出图像
* ksize:高斯滤波器模板大小,ksize的宽和高必须是奇数
* sigmaX:高斯滤波在横线的滤波系数
* sigmaY:高斯滤波在竖向的滤波系数
* 如果参数sigmaX=sigmaY=0,则实际用的是公式sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8
* borderType:边界的处理方式,一般默认
* */
Imgproc.GaussianBlur(dst, gry, new Size(7,7), 2, 2);
高斯边缘检测
Laplacian函数
convertScaleAbs()使用详解
/**
* void Laplacian(InputArray src, OutputArray dst, int depth, int ksize=1,
* double scale=1, double delta=0, int borderType=BORDER_DEFAULT )
* src:输入图像
* dst:输出图像
* depth:表示输出图像的深度
* ksize:表示拉普拉斯核的大小,1表示核的大小是三
* scale:表示是否对图像进行放大或者缩小
* delta:表示是否在输出的像素中加上一个量
* borderType:表示处理边界的方式,一般默认
* */
/**
* depth 图像元素的位深度,可以是下面的其中之一:
* 位深度 取值范围
*IPL_DEPTH_8U - 无符号8位整型 0--255
*IPL_DEPTH_8S - 有符号8位整型 -128--127
*IPL_DEPTH_16U - 无符号16位整型 0--65535
*IPL_DEPTH_16S - 有符号16位整型 -32768--32767
*IPL_DEPTH_32S - 有符号32位整型 0--65535
*IPL_DEPTH_32F - 单精度浮点数 0.0--1.0
*IPL_DEPTH_64F - 双精度浮点数 0.0--1.0
* */
/**
* void convertScaleAbs(InputArray src, OutputArray dst, double alpha = 1, double beta = 0);
* src:输入数组
* dst:输出数组
* alpha:乘数因子
* beta:偏移量
* */
Imgproc.GaussianBlur(src, dst, new Size(3,3), 0);//高斯滤波
Imgproc.cvtColor(dst,dst,Imgproc.COLOR_RGB2GRAY);//进行图像彩色空间转换,转换为灰度图
Imgproc.Laplacian(dst, gry, CvType.CV_16S, 3, 5, 0, Core.BORDER_DEFAULT);
Core.convertScaleAbs(gry,dst,3,5);
图片的文字写入
public class AlterIimage {
public static boolean createStringMark(String filePath,String markContent,String outPath)
{
ImageIcon imgIcon=new ImageIcon(filePath);
Image theImg =imgIcon.getImage();
int width=theImg.getWidth(null)==-1?200:theImg.getWidth(null);
int height= theImg.getHeight(null)==-1?200:theImg.getHeight(null);
// System.out.println(width);
// System.out.println(height);
// System.out.println(theImg);
BufferedImage bimage = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB); //将一副图片加载到内存中
Graphics2D g=bimage.createGraphics(); //创建一个指定 BufferedImage 的 Graphics2D 对象
Color mycolor = Color.GREEN;
g.setColor(mycolor);
g.setBackground(Color.GREEN);
g.drawImage(theImg, 0, 0, null );
g.setFont(new Font("宋体",Font.PLAIN,20)); //字体、字型、字号
g.drawString(markContent,20,25); //画文字
g.dispose();
try
{
FileOutputStream out=new FileOutputStream(outPath); //先用一个特定的输出文件名
/**
* Eclipse默认把这些受访问限制的API设成了ERROR。只要把Windows-Preferences-Java-Complicer-Errors/Warnings
* 里面的Deprecated and restricted API中的Forbidden references(access rules)选为Warning就可以编译通过。
* */
JPEGImageEncoder encoder =JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage);
param.setQuality(100, true);
encoder.encode(bimage, param);
out.close();
}
catch(Exception e)
{ return false; }
return true;
}
}
最后结果展示