图像处理 -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







    
评论