2011-11-30 15:22:49 honesty2008 阅读数 3108
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4440 人正在学习 去看看 贾志刚

一.实验题目

边缘检测:分别用Roberts、 Prewitt 和 Sobel算子对下图进行边缘检测,并比较三种检测结果的异同。


二.实验分析

边缘检测的检测器主要有Sobel,Prewitt,Roberts,Canny等,边缘检测的
基本意图是使用下两个基本准则之一在图像中找到亮度快速变化的地方:
①找到亮度的一阶导数在幅度上比指定的阈值大的地方
②找到亮度的二阶导数有零交叉的地方。
由于求导比较的麻烦,因此,一般用掩膜来数字化地近似一阶导数Gx和Gy。
   本实验完成方法很多,可以通过以下途径解决:①直接用edge函数
②用imfilter 模拟③直接进行模拟 。值得注意的是由于Roberts掩膜是2*2的,
一般选取3*3模板的右下角四个元素进行处理。

三.实验程序

% 代码一 直接通过edge函数检测
clear;clc;figure;
I=imread('images_chapter_10\Fig10.10(a).jpg');
subplot(2,2,1);imshow(I);title('orignal');
I1=edge(I,'sobel');
subplot(2,2,2);imshow(I1);title('sobel');
I2=edge(I,'prewitt');
subplot(2,2,3);imshow(I2);title('prewitt');
I3=edge(I,'roberts');
subplot(2,2,4);imshow(I3);title('roberts');
% 代码二 直接模拟
clear;clc;figure;
I=imread('images_chapter_10\Fig10.10(a).jpg');
subplot(2,2,1);imshow(I);title('orignal');
s1=[-1 -2 -1; 0 0 0; 1 2 1];
s2=[-1 0 1; -2 0 2; -1 0 1 ];
p1=[-1 -1 -1; 0 0 0 ;1 1 1];
p2=[-1 0 1;-1 0 1; -1 0 1 ];
r1=[-1 0 ;0 1];r2=[0 -1; 1 0];
[r,c]=size(I);I=double(I);
for u=1:r-2
    for v=1:c-2
        gx=sum(sum(I(u:u+2,v:v+2).*s1));
        gy=sum(sum(I(u:u+2,v:v+2).*s2));
        Is(u,v)=sqrt(gx*gx+gy*gy);
        gx=sum(sum(I(u:u+2,v:v+2).*p1));
        gy=sum(sum(I(u:u+2,v:v+2).*p2));
        Ip(u,v)=sqrt(gx*gx+gy*gy);
        gx=sum(sum(I(u+1:u+2,v+1:v+2).*r1));
        gy=sum(sum(I(u+1:u+2,v+1:v+2).*r2));
        Ir(u,v)=sqrt(gx*gx+gy*gy);
    end
end

Is1=Is;Ip1=Ip;Ir1=Ir;
scale=0.4;
Is2=Is1>max(max(Is1))*scale;
Ip2=Ip1>max(max(Ip1))*scale;
Ir2=Ir1>max(max(Ir1))*scale;
subplot(2,2,2);imshow(Is2,[]);title('sobel');
subplot(2,2,3);imshow(Ip2,[]);title('prewitt');
subplot(2,2,4);imshow(Ir2,[]);title('roberts');
       
程序说明:将程序二的scale赋值为0.2,效果与程序一相同

四.实验结果





2014-06-26 22:34:12 u013018721 阅读数 2072
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4440 人正在学习 去看看 贾志刚

最近由于项目需要,需要做一些边缘检测相关的工作。于是把最近几天的学习内容做一下整理。


①.基本原理


在图像处理和计算机视觉中,边缘检测被广泛使用。其目的在于标识出数字图像中亮点变化明显的点,进而提取出有用的信息。


通常情况下我们可以将数字图像表示为二位数组,而概二位数组中每个元素的值则对应着图像各个像素点的灰度值。而边缘检测


的根本原理是通过算法将该数组中各个数据邻域内数值变化大的数据元素进行突出显示,而邻域内变化不大的相邻数据元素数


据元素进行屏蔽或降低其灰度显示。


不能看出其边缘检测的很像即为如何找出一种算法来突出这种邻域内的数值变化率。



②.边缘检测算法有哪些

  

    不难看出,边缘检测算法的核心是突出图像中变化率,无论目标与目标,还是目标与背景之间。这于导数的概念离奇的详尽。而对于离散的数字图像中,我们可以使用与求导


类比的差分运算来提取图像边缘。基于此原理应用于二维数组中我们可以求出该二维数组的梯度模矩阵。该梯度模矩阵就能比较清楚的表示出图像矩阵的边缘。当然也可以设定


一个阈值,当梯度模矩阵中大于阈值的元素则保留,而低于阈值的元素则设为黑度。


   根据梯度模矩阵的不同求法,边缘检测算法可以分为两大类:一阶导数方式(梯度算子)和二阶导数方式


而一阶导数方式中几种常见的边缘算子为:Robert,Sobel,PreWitt,kvisch.

而二阶导数方式常见的有:laplace算子



③.边缘检测在图像处理中的一般步骤

 



   其中第一步为滤波,因为图像中存在噪声所以需要先进行滤波。然而数字图像中的噪声大多和边缘信号一样占据高频段,所以如果滤波


过于完全很可能连同边缘一起滤除,使得滤波后的图像变得模糊,无法提取有效的边缘。而第二步为我们通常所说的利用边缘算子对边缘进行


增强。这一步的结果便可直接当做边缘检测的结果。然而大多数边缘检测还需要进行第三部,设定阈值,对超过阈值的像素点进行突出,对低于


阈值的像素点进行屏蔽。

     


④.matlab边缘处理示例。


程序代码如下:



程序结果如下:





本文对边缘检测做了简单的概述,也是对近两天学习的总结。通过此文相信大家会对边缘检测有了大概的了解,通过最后一个示例程序使读者

对各种边缘处理的印象更加直观。文中难免出现纰漏还望读者批评指正,最后共同进步。

转载请注明文章作者:小刘

2018-11-28 17:25:45 shanwenkang 阅读数 623
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4440 人正在学习 去看看 贾志刚

边缘检测

我们之前讲边缘检测的时候讲到了一阶导和二阶导,理想边缘的像素值是跳变的,而斜坡边缘的像素值是渐变的。我们在求一阶导的时候导数值大的地方可以看做边缘;若是对于斜坡边缘,我们不想得到一长条边缘,而只想得到这个渐变的中央点时,我们可以看二阶导,二阶导只在边缘开始与结束的地方会出现,因此我们只需要找到二阶导的过零点就可以找到渐变的中央点了

在现实生活中出现的边缘更多时候带有噪声,这种情况下使得我们很难找到边缘

这种情况下我们的解决方法就是先加一个低通滤波器再进行边缘检测,这也就是我们在SOBEL滤波器中做的事情,我们可以将其看做在一个方向上做边缘检测,在另一个方向上做一个平滑滤波

边缘检测基本上与图像的梯度有关

图像的边缘与梯度垂直,因此我们可以用图像在两个方向上导数的平方和来表示图像是否存在边缘,边缘的角度由两个导数的反正切值表示

利于对于如下图像我们可以看到M与α的值,在求M的时候我们用两个方向的SOBEL滤波器对图像进行滤波来得到gx、gy(当然也可以采用[-1 1]这样简单的差分形式),再求平方和。由于这种方法采用的是一阶导,因此M大的地方表示导数值比较大,阿尔法来表示边缘的角度。通过这两幅图我们可以通过筛选某个特定的角度来实现检测特定方向的边缘,例如我们筛选M(x,y)>τ&|α(x,y)<θ|的值可以得到方向为大致为θ的边缘

高斯拉普拉斯函数

除了SOBEL算子,我们还有其他的方法可以检测一个图像的边缘,一种方法就是利用高斯拉普拉斯函数

这种方法的本质就是先利用高斯滤波器对图像进行滤波,来过滤掉乱七八糟的东西,再求拉普拉斯算子来检测图像的边缘,得到的结果像一个墨西哥帽,因此也叫墨西哥帽函数

由于这种方法采用的是二阶导,因此图像中过零点的位置是图像的边缘,我们在MATLAB中可以用fspecial加'log'参数来构造一个高斯拉普拉斯函数,再用这个函数对图像进行滤波就能得到检测结果

这种方法的好处是我们可以调整需要检测边缘的尺度,如果要检测的边缘很小,我们可以把σ调小,得到的就是左图的结果;如果需要检测大边缘,我们将高斯函数的σ调大,得到的是右图的结果,最明显的地方就是图里面鼻子的边缘消失了

为了减少计算量,我们也可以用两个高斯函数来得到高斯拉普拉斯函数作为近似

CANNY边缘检测

相对以上两种算法,CANNY边缘检测算法更加复杂,但是效果更好,它的基本思路是先对图像进行低通滤波,之后计算M与α,然后对M采用非极大值抑制算法来得到一个新的梯度图

非极大值抑制算法的思路如下,将α分成四个块(根据需求可以调整为更多的块)。由于我们在之前讲过对于斜坡边缘,它的一阶导大的值有很多,因此我们先看一个像素的阿尔法属于哪个块,再在这个特定方向上寻找比周围值都大的导数值(最能代表这个边缘)作为新的边缘,而将其他值置零就可以了

最后一部就是设定两个阈值,梯度值大于大阈值,则这个新像素的值置1;梯度值小于小阈值的像素,新像素值置0;处在两个阈值之间的值,看它是否与已经置1的像素接壤,如果是,则这个像素也置1。最后一步是为了补全两段边缘之间的间隙,从而使边缘更加完整

左图是用CANNY算法得出的结果,右图是SOBEL算子算出的结果,我们可以看到CANNY边缘检测算法确实取得了更好的效果

 

 

 

2018-12-22 09:26:43 lw18781108072 阅读数 806
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4440 人正在学习 去看看 贾志刚

1.边缘检测原理

图像边缘是图像最基本的特征,边缘在图像分析中起着重要的 作用。所谓边缘(edge)是指图像局部特征的不连续性。灰度或结构 信息的突变称为边缘,例如:灰度级的突变、颜色的突变、纹理结 构的突变。边缘是一个区域的结束,也是另一个区域的开始,利用该 特征可以分割图像。边缘检测基本思想是先检测图像中的边缘点,再按照某种策略将边缘点连接成轮廓,从而构成分割区域。由于边缘是所要提取目标和背景的分界线,提取出边缘才能将目标和背景区分开,因此边缘检测对于图像处理十分重要。

  1. 边缘检测算子的总结

1.Sobel算子

其主要用于边缘检测,在技术上它是以离散型的差分算子,用来运算图像亮度函数的梯度的近似值, Sobel算子是典型的基于一阶导数的边缘检测算子,由于该算子中引入了类似局部平均的运算,因此对噪声具有平滑作用,能很好的消除噪声的影响。Sobel算子对于象素的位置的影响做了加权,与Prewitt算子、Roberts算子相比因此效果更好。

Sobel算子包含2个模板,之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。实际使用中,常用如下两个模板来检测图像边缘。

图像的每一个像素的横向及纵向梯度近似值可用以下的公式结合,来计算梯度的大小。

G=

G代表梯度,Gx为横向模板和领域的卷积,Gy为纵向模板和领域卷积。

  1. Roberts算子

 

图像空间

模板      

GX为横向模板和领域的卷积,Gy为纵向模板和领域卷积。

  1. 拉普拉斯高斯算子(LOG)

LOG算子:是高斯和拉普拉斯的双结合,即集平滑和边沿于一身的算子模型!注意这个模型跟前面的一个滤波器很相似,就是各向异性滤波器!只不过是各向异性滤波器是高斯一阶导函数,而LOG可以看做是二阶导函数!这两个模型来源最初都是因为求导导致模板对噪声干扰敏感性比较强!

可以分开求,先求出拉普拉斯边缘检测,再用高斯滤波来减少噪点。

拉普拉斯相当于二阶微分。

公式如下

高斯卷积,函数如下

利用高斯函数可以求出高斯模板  也可以用现有模板3*3模板

 

再用拉普拉斯算子边缘检测  就可以完成拉普拉斯高斯算子边缘检测

也可以结合高斯函数和拉普拉斯算子结合得出公式

 

  1. 处理的效果展示

 

 

 

 

 

2016-07-29 17:48:00 chuifuhuo6864 阅读数 14
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4440 人正在学习 去看看 贾志刚

图像处理之边缘褪化效果

 

很多图像处理软件都提供边缘褪化效果滤镜,其实原理非常的简单,网上搜索了一把,

实现了基于Java的图像边缘褪化效果。边缘褪化效果取决于以下三个参数:

1.      设定的图像边缘宽度

2.      褪化比率– 其实质是图像融合的百分比数

3.      选择的边框颜色

 

主要原理是计算图像中的像素点到中心点的距离,对边缘像素根据褪化比率与选择的

边框颜色融合从而产生褪化效果。程序效果如下:

原图:


处理以后图像:


滤镜的完全源代码如下:

package com.process.blur.study;

import java.awt.Color;
import java.awt.image.BufferedImage;

/**
 * @author gloomy fish
 * Vignette - a photograph whose edges shade off gradually
 * 
 */
public class VignetteFilter extends AbstractBufferedImageOp {
		
	private int vignetteWidth;
	private int fade;
	private Color vignetteColor;
	
	public VignetteFilter() {
		vignetteWidth = 50;
		fade = 35;
		vignetteColor = Color.BLACK;
	}
	
	@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;
        for(int row=0; row<height; row++) {
        	int ta = 0, tr = 0, tg = 0, tb = 0;
        	for(int col=0; col<width; col++) {
            	
                int dX = Math.min(col, width - col);
                int dY = Math.min(row, height - row);
                index = row * width + col;
        		ta = (inPixels[index] >> 24) & 0xff;
                tr = (inPixels[index] >> 16) & 0xff;
                tg = (inPixels[index] >> 8) & 0xff;
                tb = inPixels[index] & 0xff;
                if ((dY <= vignetteWidth) & (dX <= vignetteWidth))
                {
                    double k = 1 - (double)(Math.min(dY, dX) - vignetteWidth + fade) / (double)fade;
                    outPixels[index] = superpositionColor(ta, tr, tg, tb, k);
                    continue;
                }

                if ((dX < (vignetteWidth - fade)) | (dY < (vignetteWidth - fade)))
                {
                	outPixels[index] = (ta << 24) | (vignetteColor.getRed() << 16) | (vignetteColor.getGreen() << 8) | vignetteColor.getBlue();
                }
                else
                {
                    if ((dX < vignetteWidth)&(dY>vignetteWidth))
                    {
                        double k = 1 - (double)(dX - vignetteWidth + fade) / (double)fade;
                        outPixels[index] = superpositionColor(ta, tr, tg, tb, k);
                    }
                    else
                    {
                        if ((dY < vignetteWidth)&(dX > vignetteWidth))
                        {
                            double k = 1 - (double)(dY - vignetteWidth + fade) / (double)fade;
                            outPixels[index] = superpositionColor(ta, tr, tg, tb, k);
                        }
                        else
                        {
                        	outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
                        }
                    }
                }
            }
        }
        
        setRGB( dest, 0, 0, width, height, outPixels );
        return dest;
	}
	
	public int superpositionColor(int ta, int red, int green, int blue, double k) {
		red = (int)(vignetteColor.getRed() * k + red *(1.0-k));
		green = (int)(vignetteColor.getGreen() * k + green *(1.0-k));
		blue = (int)(vignetteColor.getBlue() * k + blue *(1.0-k));
		int color = (ta << 24) | (clamp(red) << 16) | (clamp(green) << 8) | clamp(blue);
		return color;
	}
	
	public int clamp(int value) {
		return value > 255 ? 255 :((value < 0) ? 0 : value);
	}
	
	public int getVignetteWidth() {
		return vignetteWidth;
	}

	public void setVignetteWidth(int vignetteWidth) {
		this.vignetteWidth = vignetteWidth;
	}

	public int getFade() {
		return fade;
	}

	public void setFade(int fade) {
		this.fade = fade;
	}
	
	public Color getVignetteColor() {
		return vignetteColor;
	}

	public void setVignetteColor(Color vignetteColor) {
		this.vignetteColor = vignetteColor;
	}
	
}

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

转载于:https://my.oschina.net/abcijkxyz/blog/721452

没有更多推荐了,返回首页