java 图片处理 抠图 java抠图算法的实现
转载
OpenCV Java 二值(黑白)图像噪声滤波算法
在图像处理应用中,我们经常会遇到图像中的噪声点影响图像的分割和处理的情况,OpenCV的Java示例不多,本文给出一个OpenCV + Java环境下的图像噪声滤波算法。
OpenCV版本:3.4
Java:1.8
过滤黑白(二值)图像中的噪声点,可以指定过滤区域的大小。
算法说明:
- 输入待过滤图像(黑白二值)。
- 扩展图像(长、宽各增2),相当于在图像周围加了一圈以方便处理,减少许多的边界检测操作。
- 从第一个像素开始循环处理。
- 以指定像素为中心(同时需要考虑滤波区域的大小),提取指定区域的子图像。提取区域的大小为需过滤区域大小外加一个包围圈。
- 将所提取区域除外包围的中间部分赋值为0(黑色);
- 求子图像的均值(Core.mean());
- 如果均值不为0,则表示外包围有不为0的点(白色点),则不进行过滤。
- 如果均值为0,则表示外包围为一圈黑色点(0),则执行过滤(将原图像中间区域赋值为0)。
源码:
// 图像滤波,去除噪声点
/**
* @param src - 输入的二值(黑白)图像,算法将直接修改输入图像,返回的结果也是本参数
* @param size - 需要过滤的噪声块大小,默认为以size为大小的正方形块
*/
publicstaticvoid noiseFilter(Mat src, int size) {
// 图像高、宽
int rows = src.rows();
int cols = src.cols();
if(size < 1 || size > rows || size > cols || src.channels() != 1) {
return;
}
// 扩展图像
Mat rslt = Mat.zeros(rows+2, cols+2, CvType.CV_8UC1);
// 拷贝原图到扩展图像
Rect roi = new Rect(1, 1, cols, rows);
Mat m = rslt.submat(roi);
src.copyTo(m);
// 滤波参数准备
Mat mCheck = Mat.zeros(size+2, size+2, CvType.CV_8UC1);
Mat mMask Mat.zeros(size, size, CvType.CV_8UC1);
Rect roiCheck = new Rect(0, 0, size+2, size+2);
Rect roiMask = new Rect(1, 1, size, size);
Mat mRoiSrc, mRoiMask;
Scalar mean;
for(int i=1; i<=(rows-size+1); i++) {
for(int j=1; j<=(cols-size+1); j++) {
roiCheck.x = j-1;
roiCheck.y = i-1;
// 截取原图(实际是基于扩展后的图像操作)一部分执行检测
mRoiSrc = rslt.submat(roiCheck);
// 拷贝到检测对象以免操作影响到原图
mRoiSrc.copyTo(mCheck);
// 以黑点覆盖检测图像中心部分
mRoiMask = mCheck.submat(roiMask);
mMask.copyTo(mRoiMask);
// 求图像均值,如果不为0,则继续循环;如果为0,则执行过滤操作
mean = Core.mean(mCheck);
if((byte)mean.val[0] != 0) {
continue;
}
// 执行过滤操作
// mRoiMask为空(全黑),则以黑色小方块覆盖原图
mRoiMask = src.submat(new Rect(j-1,i-1,size,size));
mMask.copyTo(mRoiMask);
}
}
}
|
说明:
- 所示例算法基于图像背景为黑色点(值为0),前景为白色点(值为255)计算,如果黑白反转,可方便的调整代码适应。
- 算法的效率还有改进之处,当图片比较大时,可能需要秒级的处理时间。
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。