图像处理之图像梯度效果

简介: 图像处理之图像梯度效果基本思想:利用X方向与Y方向分别实现一阶微分,求取振幅,实现图像梯度效果。关于如何计算图像一阶微分参见这里:http://blog.csdn.net/jia20003/article/details/7562092使用的两种微分算子分别为Prewitt与Sobel,其中Soble在X, Y两个方向算子分别为:Prewitt在X, Y方向上梯度算子分别为:二:程序思路及实现梯度滤镜提供了两个参数:– 方向,用来要决定图像完成X方向梯度计算, Y方向梯度计算,或者是振幅计算– 算子类型,用来决定是使用sobel算子或者是prewitt算子。

图像处理之图像梯度效果


基本思想:

利用X方向与Y方向分别实现一阶微分,求取振幅,实现图像梯度效果。关于如何计算图像

一阶微分参见这里:http://blog.csdn.net/jia20003/article/details/7562092

使用的两种微分算子分别为Prewitt与Sobel,其中Soble在X, Y两个方向算子分别为:


Prewitt在X, Y方向上梯度算子分别为:


二:程序思路及实现

梯度滤镜提供了两个参数:

– 方向,用来要决定图像完成X方向梯度计算, Y方向梯度计算,或者是振幅计算

– 算子类型,用来决定是使用sobel算子或者是prewitt算子。

计算振幅的公式可以参见以前《图像处理之一阶微分应用》的文章


 三:运行效果

原图像如下:


基于Prewitt与sobel算子的XY方向振幅效果如下:



该滤镜的源代码如下:

package com.process.blur.study;

import java.awt.image.BufferedImage;
/**
 * 
 * @author gloomy-fish
 * @date 2012-06-11
 * 
 * prewitt operator 
 * X-direction
 * -1, 0, 1
 * -1, 0, 1
 * -1, 0, 1
 * 
 * Y-direction
 * -1, -1, -1
 *  0,  0,  0
 *  1,  1,  1
 *  
 * sobel operator
 * X-direction
 * -1, 0, 1
 * -2, 0, 2
 * -1, 0, 1
 * 
 * Y-direction
 * -1, -2, -1
 *  0,  0,  0
 *  1,  2,  1
 *
 */
public class GradientFilter extends AbstractBufferedImageOp {

	// prewitt operator
	public final static int[][] PREWITT_X = new int[][]{{-1, 0, 1}, {-1, 0, 1}, {-1, 0, 1}};
	public final static int[][] PREWITT_Y = new int[][]{{-1, -1, -1}, {0,  0,  0}, {1,  1,  1}};
	
	// sobel operator
	public final static int[][] SOBEL_X = new int[][]{{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
	public final static int[][] SOBEL_Y = new int[][]{{-1, -2, -1}, {0,  0,  0}, {1,  2,  1}};
	
	// direction parameter
	public final static int X_DIRECTION = 0;
	public final static int Y_DIRECTION = 2;
	public final static int XY_DIRECTION = 4;
	private int direction;
	private boolean isSobel;
	
	public GradientFilter() {
		direction = XY_DIRECTION;
		isSobel = true;
	}
	
	public void setSoble(boolean sobel) {
		this.isSobel = sobel;
	}

	public int getDirection() {
		return direction;
	}

	public void setDirection(int direction) {
		this.direction = direction;
	}
	
	@Override
	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
		int width = src.getWidth();
        int height = src.getHeight();

        if (dest == null )
        	dest = createCompatibleDestImage( src, null );

        int[] inPixels = new int[width*height];
        int[] outPixels = new int[width*height];
        getRGB( src, 0, 0, width, height, inPixels );
        int index = 0, index2 = 0;
        double xred = 0, xgreen = 0, xblue = 0;
        double yred = 0, ygreen = 0, yblue = 0;
        int newRow, newCol;
        for(int row=0; row<height; row++) {
        	int ta = 255, tr = 0, tg = 0, tb = 0;
        	for(int col=0; col<width; col++) {
        		index = row * width + col;
        		for(int subrow = -1; subrow <= 1; subrow++) {
        			for(int subcol = -1; subcol <= 1; subcol++) {
        				newRow = row + subrow;
        				newCol = col + subcol;
        				if(newRow < 0 || newRow >= height) {
        					newRow = row;
        				}
        				if(newCol < 0 || newCol >= width) {
        					newCol = col;
        				}
        				index2 = newRow * width + newCol;
                        tr = (inPixels[index2] >> 16) & 0xff;
                        tg = (inPixels[index2] >> 8) & 0xff;
                        tb = inPixels[index2] & 0xff;
                        
                        if(isSobel) {
                        	xred += (SOBEL_X[subrow + 1][subcol + 1] * tr);
                        	xgreen +=(SOBEL_X[subrow + 1][subcol + 1] * tg);
                        	xblue +=(SOBEL_X[subrow + 1][subcol + 1] * tb);
                        	
                        	yred += (SOBEL_Y[subrow + 1][subcol + 1] * tr);
                        	ygreen +=(SOBEL_Y[subrow + 1][subcol + 1] * tg);
                        	yblue +=(SOBEL_Y[subrow + 1][subcol + 1] * tb);
                        } else {
                        	xred += (PREWITT_X[subrow + 1][subcol + 1] * tr);
                        	xgreen +=(PREWITT_X[subrow + 1][subcol + 1] * tg);
                        	xblue +=(PREWITT_X[subrow + 1][subcol + 1] * tb);
                        	
                        	yred += (PREWITT_Y[subrow + 1][subcol + 1] * tr);
                        	ygreen +=(PREWITT_Y[subrow + 1][subcol + 1] * tg);
                        	yblue +=(PREWITT_Y[subrow + 1][subcol + 1] * tb);
                        }
        			}
        		}
        		
                double mred = Math.sqrt(xred * xred + yred * yred);
                double mgreen = Math.sqrt(xgreen * xgreen + ygreen * ygreen);
                double mblue = Math.sqrt(xblue * xblue + yblue * yblue);
                if(XY_DIRECTION == direction) 
                {
                	outPixels[index] = (ta << 24) | (clamp((int)mred) << 16) | (clamp((int)mgreen) << 8) | clamp((int)mblue);
                } 
                else if(X_DIRECTION == direction)
                {
                	outPixels[index] = (ta << 24) | (clamp((int)yred) << 16) | (clamp((int)ygreen) << 8) | clamp((int)yblue);
                } 
                else if(Y_DIRECTION == direction) 
                {
                	outPixels[index] = (ta << 24) | (clamp((int)xred) << 16) | (clamp((int)xgreen) << 8) | clamp((int)xblue);
                } 
                else 
                {
                	// as default, always XY gradient
                	outPixels[index] = (ta << 24) | (clamp((int)mred) << 16) | (clamp((int)mgreen) << 8) | clamp((int)mblue);
                }
                
                // cleanup for next loop
                newRow = newCol = 0;
                xred = xgreen = xblue = 0;
                yred = ygreen = yblue = 0;
                
        	}
        }
        setRGB(dest, 0, 0, width, height, outPixels );
        return dest;
	}
	
	public static int clamp(int value) {
		return value < 0 ? 0 : (value > 255 ? 255 : value);
	}

}

转载文章请务必注明出自本博客!

精彩内容查看 - 《数字图像处理-空间域卷积视频教程》

目录
相关文章
|
2天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
13天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1286 5
|
12天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1318 87
|
1天前
|
弹性计算 安全 数据安全/隐私保护
2025年阿里云域名备案流程(新手图文详细流程)
本文图文详解阿里云账号注册、服务器租赁、域名购买及备案全流程,涵盖企业实名认证、信息模板创建、域名备案提交与管局审核等关键步骤,助您快速完成网站上线前的准备工作。
175 82
2025年阿里云域名备案流程(新手图文详细流程)
|
1天前
|
自然语言处理 前端开发
基于Electron38+Vite7.1+Vue3+Pinia3+ElementPlus电脑端admin后台管理模板
基于最新版跨平台框架Electron38整合Vite7+Vue3+ElementPlus搭建轻量级客户端中后台管理系统解决方案。
152 86