图像处理 -Java- 字深字浅
作者:alexgaoyh
- 2024-02-20 河南
本文字数:3263 字
阅读完需:约 11 分钟
背景
《图像处理-Java-字深字浅》,之前在编写过关于图像边缘检测-去黑边、图像边缘检测-自动纠偏、图像处理-锐化、图像处理-去噪/高斯模糊/套红、图像处理-背景色平滑/反色、图像处理-指定大小压缩等一系列文章,接下来主要介绍图像字体变深/变浅操作。
概述
使用 JAVA 语言实现,实现思路是获得图像的边缘,判断边缘部分与白色像素点的相似度,对得到的边缘像素点在原始图像上进行像素点的调整(添加/减少),从而实现边缘部分的变深/变浅操作。
实现效果示例
首先输入图像仍保持不变,输出分别是: 原图、字深图像、字浅图像。
字深字浅-原图
字深字浅-字深图
字深字浅-字浅图
图像备份: 访问
代码实现
/**
* 在使用Prewitt算子获得图像边缘后,你可以将边缘信息与原图进行叠加处理来处理图像。
* @param originalImage
* @param threshold 阈值 30
* @param scope 字深字浅幅度 : 字浅(threshold=30 && scope=60)、字深(threshold=30 && scope=-60)
* @return
*/
public static BufferedImage prewitterWithFontWeight(BufferedImage originalImage, int threshold, int scope) {
// 获得Prewitt边缘图
BufferedImage edgeImage = applyPrewittOperator(originalImage);
// 将边缘图与原图叠加
BufferedImage overlayImages = overlayFontWeight(originalImage, edgeImage, threshold, scope);
return overlayImages;
}
private static BufferedImage overlayFontWeight(BufferedImage originalImage, BufferedImage edgeImage, int threshold, int scope) {
int width = originalImage.getWidth();
int height = originalImage.getHeight();
BufferedImage resultImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// 获取原图和边缘图的像素值
int originalPixel = originalImage.getRGB(x, y);
int edgePixel = edgeImage.getRGB(x, y);
// 将边缘图的灰度值作为权重,这里简化为取Red分量
int edgeWeight = (edgePixel >> 16) & 0xFF;
// 忽略较小的边缘信息(根据阈值设定)
if (edgeWeight < threshold) {
resultImage.setRGB(x, y, originalPixel);
} else {
// 将原图和边缘图叠加,这里可以根据需求进行调整
int combinedRed = Math.min(255, ((originalPixel >> 16) & 0xFF) + scope);
int combinedGreen = Math.min(255, ((originalPixel >> 8) & 0xFF) + scope);
int combinedBlue = Math.min(255, (originalPixel & 0xFF) + scope);
// 合并颜色值
int combinedPixel = (combinedRed << 16) | (combinedGreen << 8) | combinedBlue;
// 设置叠加后的像素值
resultImage.setRGB(x, y, combinedPixel);
}
}
}
return resultImage;
}
private static BufferedImage applyPrewittOperator(BufferedImage originalImage) {
int width = originalImage.getWidth();
int height = originalImage.getHeight();
BufferedImage sharpenedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 定义Prewitt水平和垂直算子
int[][] horizontalOperator = {
{-1, 0, 1},
{-1, 0, 1},
{-1, 0, 1}
};
int[][] verticalOperator = {
{-1, -1, -1},
{ 0, 0, 0},
{ 1, 1, 1}
};
// 应用水平Prewitt算子
BufferedImage horizontalResult = applyConvolution(originalImage, horizontalOperator);
// 应用垂直Prewitt算子
BufferedImage verticalResult = applyConvolution(originalImage, verticalOperator);
// 合并水平和垂直结果
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int horizontalPixel = horizontalResult.getRGB(x, y);
int verticalPixel = verticalResult.getRGB(x, y);
// 取水平和垂直梯度的平方和的平方根
int combinedPixel = combinePixels(horizontalPixel, verticalPixel);
sharpenedImage.setRGB(x, y, combinedPixel);
}
}
return sharpenedImage;
}
private static BufferedImage applyConvolution(BufferedImage image, int[][] operator) {
int width = image.getWidth();
int height = image.getHeight();
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int operatorSize = operator.length;
int offset = operatorSize / 2;
// 归一化权重
int weightSum = 0;
for (int[] row : operator) {
for (int value : row) {
weightSum += Math.abs(value);
}
}
if (weightSum == 0) {
weightSum = 1; // 防止除以零错误
}
for (int y = offset; y < height - offset; y++) {
for (int x = offset; x < width - offset; x++) {
int sumRed = 0;
int sumGreen = 0;
int sumBlue = 0;
for (int i = 0; i < operatorSize; i++) {
for (int j = 0; j < operatorSize; j++) {
int pixel = image.getRGB(x - offset + i, y - offset + j);
int weight = operator[i][j];
sumRed += weight * ((pixel >> 16) & 0xFF);
sumGreen += weight * ((pixel >> 8) & 0xFF);
sumBlue += weight * (pixel & 0xFF);
}
}
// 归一化颜色值
sumRed = Math.min(255, Math.max(0, sumRed / weightSum));
sumGreen = Math.min(255, Math.max(0, sumGreen / weightSum));
sumBlue = Math.min(255, Math.max(0, sumBlue / weightSum));
int combinedPixel = (sumRed << 16) | (sumGreen << 8) | sumBlue;
result.setRGB(x, y, combinedPixel);
}
}
return result;
}
private static int combinePixels(int pixel1, int pixel2) {
int red1 = (pixel1 >> 16) & 0xFF;
int green1 = (pixel1 >> 8) & 0xFF;
int blue1 = pixel1 & 0xFF;
int red2 = (pixel2 >> 16) & 0xFF;
int green2 = (pixel2 >> 8) & 0xFF;
int blue2 = pixel2 & 0xFF;
int combinedRed = (int) Math.sqrt(red1 * red1 + red2 * red2);
int combinedGreen = (int) Math.sqrt(green1 * green1 + green2 * green2);
int combinedBlue = (int) Math.sqrt(blue1 * blue1 + blue2 * blue2);
return (combinedRed << 16) | (combinedGreen << 8) | combinedBlue;
}
复制代码
参考
划线
评论
复制
发布于: 刚刚阅读数: 6
版权声明: 本文为 InfoQ 作者【alexgaoyh】的原创文章。
原文链接:【http://xie.infoq.cn/article/3d16223230199c293bd41ec9c】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
alexgaoyh
关注
DevOps 2013-12-08 加入
https://gitee.com/alexgaoyh
评论