2017-04-04 18:27:25 Mahabharata_ 阅读数 12731
  • Java经典算法讲解

    在面试中,算法题目是必须的,通过算法能够看出一个程序员的编程思维,考察对复杂问题的设计与分析能力,对问题的严谨性都能够体现出来。一个算法的好坏,直接影响一个方法调用的性能,进而影响软件的整体性能。算法是学习所有编程语言的基础,在Java的学习过程中首先也会选择以算法起步,本次课程重点讲解Java开发中常用的基本算法。

    29961 人正在学习 去看看 张中强

完成时间:2017/1/23 

我的实现结果如下:(图一为原图,图二为边缘检测结果)

               

              

关于Sobel算子(英文部分来源于Wikipedia)

         The Sobel operator, sometimes called the Sobel–Feldman operator or Sobel filter, is used inimage processing and computer vision, particularly within edge detection algorithms where it creates an image emphasising edges. It is named after Irwin Sobel and Gary Feldman, colleagues at the Stanford Artificial Intelligence Laboratory (SAIL).

     Sobel算子,也被称为Sobel-Feldman算子,或者Sobel滤波,是在图像处理和计算机视觉得到广泛应用的一种图像边缘检测算法。它由斯坦福大学人工智能实验室(SAIL)的Irwin Sobel和Gray Feldman而得名(在此膜拜数学大神!)。

     The operator uses two 3×3 kernels which are convolved with the original image to calculate approximations of the derivatives – one for horizontal changes, and one for vertical. If we define A as the source image, and Gx and Gy are two images which at each point contain the horizontal and vertical derivative approximations respectively, the computations are as follows:

    Sobel算子使用两个(3x3)矩阵来对原图进行卷积运算以计算出两个方向的灰度差分(偏导)的估计值(一个水平方向、一个竖直方向)。我们假定A是原始图像(彩色图像需先转换为灰度图像Gx和Gy分别是在横向及纵向的灰度偏导的近似值(即两个方向上对原图的平面卷积结果)。数学表达如下:

     

    对应的计算过程如下:

       Gx = [ f(x+1,y-1)+2*f(x+1,y)+f(x+1,y+1)] - [f(x-1,y-1)+2*f(x-1,y)+f(x-1,y+1) ]
       Gy = [ f(x-1,y-1) + 2f(x,y-1) + f(x+1,y-1)] - [f(x-1, y+1) + 2*f(x,y+1)+f(x+1,y+1) 

    上式中,f(x,y)为图像A中(x,y)处的灰度值。由此便可以计算出每个点的Gx和Gy。


    At each point in the image, the resulting gradient approximations can be combined to give the gradient magnitude, using:

   对于图像中的每个点,其梯度的估计值G便可以通过两个方向的梯度Gx和Gy借由下式得出:

     

   此时,我们只需要设定一个阈值Gmax(比如说:100,一般来讲0-255左右为宜),若梯度G大于阈值Gmax,则可认为该点是一个边界点

   Using this information, we can also calculate the gradient's direction:

   当然,我们甚至可以通过Gx和Gy求得边界点梯度变化的方向,只需应用下式即可。

   

2016-10-06 16:21:43 jia20003 阅读数 6664
  • Java经典算法讲解

    在面试中,算法题目是必须的,通过算法能够看出一个程序员的编程思维,考察对复杂问题的设计与分析能力,对问题的严谨性都能够体现出来。一个算法的好坏,直接影响一个方法调用的性能,进而影响软件的整体性能。算法是学习所有编程语言的基础,在Java的学习过程中首先也会选择以算法起步,本次课程重点讲解Java开发中常用的基本算法。

    29961 人正在学习 去看看 张中强

图像处理之积分图应用二(快速边缘保留滤波算法)

一:基本原理

传统的图像边缘保留滤波算法-如高斯双边模糊、Mean-Shift模糊等计算复杂、效率比较低,虽然有各种手段优化或者快速计算方法,当时算法相对一般码农来说理解起来比较费劲,不是一个的选择,而通过积分图像实现局部均方差的边缘保留模糊算法,计算简单而且可以做到计算量跟半径无关、跟上面提到两种边缘保留滤波(EPF)算法效率高很多。首先局部均方差滤波中计算局部均值的公式如下:

当边缘很弱的时候系数K趋近于0、该点的矫正之后的像素值就接近平均值。而当边缘很强的时候系数K趋近于1、该点的模糊之后的像素值就接近等于输入像素值。上述计算中最中意的是窗口内像素的均值与方差,计算均值可以根据积分图像很容易得到,而计算方差根据一系列的数学推导可以得到如下:


就是说可以根据积分图像通过常量次数的计算得到局部的均值与方差,让这种情况下的滤波变成一个常量时间完成的操作与窗口半径大小无关。

二:算法流程

1. 根据输入的图像计算得到积分图像,参见《图像处理之积分图像算法》

2. 根据输入的半径大小计算窗口内像素均值与方差、计算得到每个像素新的像素值

3. 循环每个个像素,重复第2步计算,得到最终的局部均方差滤波图像

三:代码实现

package com.gloomyfish.ii.demo;

import java.awt.image.BufferedImage;

/**
 * fast edge preserve filter algorithm base on integral image
 * @author zhigang jia
 * @E-mail:bfnh1998@hotmail.com
 *
 */
public class FastEPFilter extends AbstractImageOptionFilter {
	// 窗口半径大小
	private int xr;
	private int yr;
	private float sigma;
	public FastEPFilter() {
	}
	
	public void setWinsize(int radius) {
		this.xr = radius;
		this.yr = radius;
	}

	public float getSigma() {
		return sigma;
	}

	public void setSigma(float sigma) {
		this.sigma = sigma;
	}

	@Override
	public BufferedImage process(BufferedImage image) {
		long time = System.currentTimeMillis();
		int width = image.getWidth();
		int height = image.getHeight();
		// get image data
		int[] pixels = new int[width * height];
		int[] outPixels = new int[width * height];
		getRGB(image, 0, 0, width, height, pixels);
		int size = (xr * 2 + 1) * (yr * 2 + 1);
		int r = 0, g = 0, b = 0;
		float sigma2 = sigma*sigma;
		
		// per-calculate integral image
		byte[] R = new byte[width*height];
		byte[] G = new byte[width*height];
		byte[] B = new byte[width*height];
		getRGB(width, height, pixels, R, G, B);
		IntIntegralImage rii = new IntIntegralImage();
		rii.setImage(R);
		rii.process(width, height);
		IntIntegralImage gii = new IntIntegralImage();
		gii.setImage(G);
		gii.process(width, height);
		IntIntegralImage bii = new IntIntegralImage();
		bii.setImage(B);
		bii.process(width, height);
		int index = 0;
		
		for (int row = yr; row < height - yr; row++) {
			for (int col = xr; col < width - xr; col++) {
				index = row * width + col;
				r = ((pixels[index] >> 16) & 0xff);
				g = (pixels[index] >> 8) & 0xff;
				b = (pixels[index] & 0xff);
				
				int sr = rii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
				int sg = gii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
				int sb = bii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
				
				float vr = rii.getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
				float vg = gii.getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
				float vb = bii.getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
				
				// 计算均值
				float mr = sr / size;
				float mg = sg / size;
				float mb = sb / size;
				
				// 计算方差
				float dr = (vr - (sr*sr)/size)/size;
				float dg = (vg - (sg*sg)/size)/size;
				float db = (vb - (sb*sb)/size)/size;
				
				// 计算系数K
				float kr = dr / (dr+sigma2);
				float kg = dg / (dg+sigma2);
				float kb = db / (db+sigma2);
				
				// 得到滤波后的像素值
				r = (int)((1-kr)*mr + kr*r);
				g = (int)((1-kg)*mg + kg*g);
				b = (int)((1-kb)*mb + kb*b);
				
				outPixels[row * width + col] = (0xff << 24) | (clamp(r) << 16) | (clamp(g) << 8) | clamp(b);
			}
		}
		System.out.println("FastEPFilter ->> time duration : " + (System.currentTimeMillis() - time));
		BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		setRGB(dest, 0, 0, width, height, outPixels);
		return dest;
	}
	
	/** Returns the red, green and blue planes as 3 byte arrays. */
	public void getRGB(int width, int height, int[] pixels, byte[] R, byte[] G, byte[] B) {
		int c, r, g, b;
		for (int i=0; i < width*height; i++) {
			c = pixels[i];
			r = (c&0xff0000)>>16;
			g = (c&0xff00)>>8;
			b = c&0xff;
			R[i] = (byte)r;
			G[i] = (byte)g;
			B[i] = (byte)b;
		}
	}

}

四:运行效果

半径设置为5,即窗口大小为5的时候,调整参数sigma的值即可得到此效果

其实很多磨皮的算法都是基于这个算法实现的,这个才是我想说的重点,

只有耐心看到此处才可以得到正确的答案。

五:参考:

http://imagej.net/Integral_Image_Filters#Variance

http://www.activovision.com/octavi/doku.php?id=integral_images


2016-07-26 09:49:21 qq_19891827 阅读数 1185
  • Java经典算法讲解

    在面试中,算法题目是必须的,通过算法能够看出一个程序员的编程思维,考察对复杂问题的设计与分析能力,对问题的严谨性都能够体现出来。一个算法的好坏,直接影响一个方法调用的性能,进而影响软件的整体性能。算法是学习所有编程语言的基础,在Java的学习过程中首先也会选择以算法起步,本次课程重点讲解Java开发中常用的基本算法。

    29961 人正在学习 去看看 张中强
图像处理,听起来是个十分高深的学问,貌似需要用到一些很深奥的数学知识,让人望而却步。其实在前端角度看,利用html5的canvas技术即可实现简单的图像处理,同时不需要很高深的数学知识,只要你有高中以上的数学水平,足矣。本篇博文主要探讨利用canvas技术,查找图像边缘的算法思路,同时贴出本人写出的查找边缘算法的详细代码。

在正式开始之前首先介绍两个处理图像问题常用的html5的API:

一、处理图像问题常用的html5的API.
(1).HTML5 canvas getImageData() 方法;
getImageData() 方法返回一个 ImageData 对象,该方法下的data对象,以一维数组的方式拷贝了画布指定矩形的像素数据。
对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:
R - 红色 (0-255)
G - 绿色 (0-255)
B - 蓝色 (0-255)
A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)。
简单来说,图像画面在网页中是以像素作为最小单位的,每幅图像以网格形式分为若干像素块,每一像素块上只有一种颜色,足够大量这样的像素块拼凑在一起形成了一幅完整的图像。以下图(左)中一朵花为例,将其放大一定倍数得到下图(右),可以看到图2中花朵被以网格形式分成若干块,这里的每一个块就是一个像素。



下面介绍一下图像颜色,网页中图像多以RGB颜色模式来呈现的,在RGB模式下图像通过3种颜色,R - 红色 (0-255),G - 绿色 (0-255),B - 蓝色 (0-255),将这3种颜色按不同比例混合后会得到其他任何颜色。
回到getImageData() 方法,该方法下data对象以一维数组形式保存了画布中所有图像的像素数据,每个像素中都保存着四个信息,除上面介绍的RGB颜色信息外,还保存了A - alpha 通道,也就是像素块的透明度情况.以画布中前两个像素为例,在data数组中的存储方式如下:data[0]="R(第一个像素点红色颜色值)",data[1]="G(第一个像素点绿色颜色值)",data[2]="B(第一个像素点蓝色颜色值)",data[3]="A(第一个像素点透明度信息)",data[4]="R(第二个像素点红色颜色值)",data[5]="G(第二个像素点绿色颜色值)",data[6]="B(第二个像素点蓝色颜色值)",data[7]="A(第二个像素点透明度信息)"......以此类推保存画布中图像的所有像素点信息。
语法:var imgData=context.getImageData(x,y,width,height);

参数 描述
x 开始复制的左上角位置的 x 坐标。
y 开始复制的左上角位置的 y 坐标。
width 将要复制的矩形区域的宽度。
height 将要复制的矩形区域的宽度

(2).putImageData() 方法:

将图像数据(从指定的 ImageData 对象)放回画布上。即将包含图像所有像素RGBA信息的对象,绘制为真实图像。
语法:context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);

参数 描述
imgData
规定要放回画布的 ImageData 对象。
x ImageData 对象左上角的 x 坐标。
y
ImageData 对象左上角的 y 坐标。
dirtyX
水平值,在画布上放置图像的位置。
dirtyY
水平值(y),在画布上放置图像的位置
dirtyWidth
在画布上绘制图像所使用的宽度
dirtyHeight
在画布上绘制图像所使用的高度

二、查找图像边缘算法思路
(1)黑白二值化:首先对图像进行黑白二值化处理,通过getImageData()方法获取画布中图像的所有像素的RGBA信息,以128为界,与data数组中每个RGBA值作对比,低于128则将其数值变为0,高于128将其数值变为255,经过此阶段处理后,图像中只保留黑、白两个颜色,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。下图(左)为原图,下图(右)为经黑白二值化处理后的图像。

               
具体前端javascript代码如下:
    

var cvs=document.getElementById('canvas');
    var HEIGHT=cvs.height;
    var WIDTH=cvs.width;
    var ctx=cvs.getContext('2d');
    var pixel = null;
    var opixel=null;
    var xpixel=null;
    var edge=[];
    var img=new Image();
    img.src='http://ui.yidaochn.com/test/zz.jpg';
    img.onload=function(){
        ctx.drawImage(img,0,0,WIDTH,HEIGHT);
        pixel = (ctx.getImageData(0, 0, WIDTH, HEIGHT));
        whiteBlack();
    };


 //黑白二值化
    function whiteBlack(){
        var red=0;
        var green=0;
        var blue=0;
        var index=null;
        var average=null;
        for(var i=0;i<HEIGHT;i++) {
            for (var j = 0; j < WIDTH; j++) {
                index=(pixel.width*i+j)*4;
                red=index;
                green=index+1;
                blue=index+2;
                average=Math.round((pixel.data[red]+pixel.data[green]+pixel.data[blue])/3);
                if(average>=128){
                    pixel.data[red]=255;
                    pixel.data[green]=255;
                    pixel.data[blue]=255;
                }else{
                    pixel.data[red]=0;
                    pixel.data[green]=0;
                    pixel.data[blue]=0;
                }
            }
        }
        ctx.putImageData(pixel,0,0);
    }


(2)边缘查找:经过黑白二值化处理后的图像仅保留两种颜色(黑、白),对存有该图像RGBA值信息的data数组进行遍历,每个像素点上的RGB值一定为黑色(0,0,0)或白色(255,255,255)。所以这里我们仅仅比较每一像素点上R值(红色值)与其上、下、左、右相邻像素点的R值是否相等即可,如改点与上下左右4个点的R值相同说明该点不是图像图形的边缘,如该点与至少上下左右4个点其中一个点R值不同,则说明该点为图形边缘,以此类推遍历所有颜色值数据即可得到图像边缘。

具体前端javascript代码如下:(为便于观察,已将边缘颜色填充为红色)
   

function imageEdge(){
        opixel=ctx.getImageData(0,0,WIDTH,HEIGHT);
        var red=0;
        var index=null;
        var redVal=null;
        var prevRedVal=null;
        var nextRedVal=null;
        var topRedVal=null;
        var bottomRedVal=null;


        for(var i=0;i<HEIGHT;i++){
            for(var j=0;j<WIDTH;j++){
                index=(pixel.width*i+j)*4;
                red=index;
                redVal=pixel.data[red];
                prevRedVal=red-4>=0?pixel.data[red-4]:pixel.data[red];
                nextRedVal=pixel.data[red+4];
                topRedVal=(red-WIDTH*4)>=0?pixel.data[red-WIDTH*4]:pixel.data[red];
                bottomRedVal=pixel.data[red+WIDTH*4];


                if(redVal!=nextRedVal||redVal!=topRedVal||redVal!=prevRedVal||redVal!=bottomRedVal){
                    opixel.data[red]=255;
                    edge.push(red);
                }
            }
        }
        ctx.putImageData(opixel,0,0);
    }

经查找边缘操作后的图像如下图所示(边缘已标红),是不是觉得算法是如此简单,有种豁然开朗的感觉。


2015-07-09 21:45:50 u013580497 阅读数 1908
  • Java经典算法讲解

    在面试中,算法题目是必须的,通过算法能够看出一个程序员的编程思维,考察对复杂问题的设计与分析能力,对问题的严谨性都能够体现出来。一个算法的好坏,直接影响一个方法调用的性能,进而影响软件的整体性能。算法是学习所有编程语言的基础,在Java的学习过程中首先也会选择以算法起步,本次课程重点讲解Java开发中常用的基本算法。

    29961 人正在学习 去看看 张中强




实现效果:


源码地址:

http://download.csdn.net/detail/u013580497/8877185


2019-08-21 17:06:49 baidu_34971492 阅读数 218
  • Java经典算法讲解

    在面试中,算法题目是必须的,通过算法能够看出一个程序员的编程思维,考察对复杂问题的设计与分析能力,对问题的严谨性都能够体现出来。一个算法的好坏,直接影响一个方法调用的性能,进而影响软件的整体性能。算法是学习所有编程语言的基础,在Java的学习过程中首先也会选择以算法起步,本次课程重点讲解Java开发中常用的基本算法。

    29961 人正在学习 去看看 张中强

FPGA图像处理之边缘检测算法的实现

1.背景知识

边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。 这些包括(i)深度上的不连续、(ii)表面方向不连续、(iii)物质属性变化和(iv)场景照明变化。 边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域。

2.边缘检测算子

一阶:Roberts Cross算子,Prewitt算子,Sobel算子, Kirsch算子,罗盘算子;二阶: Marr-Hildreth,在梯度方向的二阶导数过零点,Canny算子,Laplacian算子。今天我们要讲的是基于Sobel算子的边缘检测的FPGA算法的实现。

3.Sobel算子实现

Sobel算法是像素图像边缘检测中最重要的算子之一,在机器学习、数字媒体、计算机视觉等信息科技领域起着举足轻重的作用。在技术上,它是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度之近似值。在图像的任何一点使用此算子,将会产生该点对应的梯度矢量或是其法矢量
Soble边缘检测算法比较简,实际应用中效率比canny边缘检测效率要高,但是边缘不如Canny检测的准确,但是很多实际应用的场合,sobel边缘却是首选,尤其是对效率要求较高,而对细纹理不太关心的时候。
Soble边缘检测通常带有方向性,可以只检测竖直边缘或垂直边缘或都检测。
-1 0 +1
-2 0 +2
-1 0 +1
Sobel算子 x方向
+1 +2 +1
0 0 0
-1 -2 -1

Y方向

(i-1,j-1) ( i,j-1) (i+1,j-1)
(i-1,j) (i,j) (i+1,j)
(i-1,j+1) (i,j+1) (i+1,j+1)

原始图像P
实现步骤:

 1.Gx = P ★Sobelx   -- 原始图像与Sobel算子X方向卷积;
 2.  Gy = P★Sobely   -- 原始图像与Sobel算子Y方向卷积;
  1. 在这里插入图片描述
  2. 阈值比较形成边缘查找后的二值图像。

4.C语言实现

/* Sobel template
a00 a01 a02
a10 a11 a12
a20 a21 a22
*/
unsigned char a00, a01, a02;
unsigned char a10, a11, a12;
unsigned char a20, a21, a22;
void MySobel(IplImage* gray, IplImage* gradient)
{
CvScalar color ;
for (int i=1; i<gray->height-1; ++i)
{
for (int j=1; j<gray->width-1; ++j)
{
a00 = cvGet2D(gray, i-1, j-1).val[0];
a01 = cvGet2D(gray, i-1, j).val[0];
a02 = cvGet2D(gray, i-1, j+1).val[0];
a10 = cvGet2D(gray, i, j-1).val[0];
a11 = cvGet2D(gray, i, j).val[0];
a12 = cvGet2D(gray, i, j+1).val[0];
a20 = cvGet2D(gray, i+1, j-1).val[0];
a21 = cvGet2D(gray, i+1, j).val[0];
a22 = cvGet2D(gray, i+1, j+1).val[0];
// x方向上的近似导数  卷积运算
double ux = a20 * (1) + a10 * (2) + a00 * (1)
+ (a02 * (-1) + a12 * (-2) + a22 * (-1));
// y方向上的近似导数  卷积运算
double uy = a02 * (1) + a01 * (2) + a00 * (1)
+ a20 * (-1) + a21 * (-2) + a22 * (-1);
color.val[0] = sqrt(ux*ux + uy*uy);
cvSet2D(gradient, i, j, color);
}
}
}
//注释:该程序需要在安装Opencv软件下运行。

5.Matlab边缘检测的实现

ps=imread('lena.jpg'); %读取图像
subplot(1,3,1)
imshow(ps);
title('原图像');
ps=rgb2gray(ps);
[m,n]=size(ps); %用Sobel微分算子进行边缘检测
pa = edge(ps,'sobel');
subplot(1,3,2);
imshow(pa);
title('Sobel边缘检测得到的图像');

结果:
在这里插入图片描述

效果图

6.FPGA实现

我将在FPGA程序中注释,表示实现过程。我们使用的图像为480x272。

/* 
Filename    : Sobel.v
Compiler    : Quartus II 13.0
Description : implement Sobel Edge Detector 
Release     : 
*/

module sobel (
  input            iCLK,
  input            iRST_N,
  input      [7:0] iTHRESHOLD,
  input            iDVAL,
  input      [9:0] iDATA,
  output reg       oDVAL,
  output reg [9:0] oDATA
);
//----------------------------------------------------
// 将Sobel算子换算成有符号数(signed)
//----------------------------------------------------
// mask x
parameter X1 = 8'hff, X2 = 8'h00, X3 = 8'h01;
parameter X4 = 8'hfe, X5 = 8'h00, X6 = 8'h02;
parameter X7 = 8'hff, X8 = 8'h00, X9 = 8'h01;

// mask y
parameter Y1 = 8'h01, Y2 = 8'h02, Y3 = 8'h01;
parameter Y4 = 8'h00, Y5 = 8'h00, Y6 = 8'h00;
parameter Y7 = 8'hff, Y8 = 8'hfe, Y9 = 8'hff;

wire  [7:0] Line0;
wire  [7:0] Line1;
wire  [7:0] Line2;

wire  [17:0]  Mac_x0;
wire  [17:0]  Mac_x1;
wire  [17:0]  Mac_x2;

wire  [17:0]  Mac_y0;
wire  [17:0]  Mac_y1;
wire  [17:0]  Mac_y2;

wire  [19:0]  Pa_x;
wire  [19:0]  Pa_y;

wire  [15:0]  Abs_mag;
//---------------------------------------------
// 实现3x3矩阵原始图像 P
//---------------------------------------------
LineBuffer LineBuffer_inst (
  .clken(iDVAL),
  .clock(iCLK),
  .shiftin(iDATA[9:2]),
  .taps0x(Line0),
  .taps1x(Line1),
  .taps2x(Line2)
);
//--------------------------------------------
// Gx = P ★Sobelx
// x方向卷积运算实现
//---------------------------------------------
MAC_3 x0 (
  .aclr3(!iRST_N),
  .clock0(iCLK),
  .dataa_0(Line0),
  .datab_0(X9),
  .datab_1(X8),
  .datab_2(X7),
  .result(Mac_x0)
);

MAC_3 x1 (
  .aclr3(!iRST_N),
  .clock0(iCLK),
  .dataa_0(Line1),
  .datab_0(X6),
  .datab_1(X5),
  .datab_2(X4),
  .result(Mac_x1)
);

MAC_3 x2 (
  .aclr3(!iRST_N),
  .clock0(iCLK),
  .dataa_0(Line2),
  .datab_0(X3),
  .datab_1(X2),
  .datab_2(X1),
  .result(Mac_x2)
);
PA_3 pa0 (
  .clock(iCLK),
  .data0x(Mac_x0),
  .data1x(Mac_x1),
  .data2x(Mac_x2),
  .result(Pa_x)
);

//---------------------------------------------------
// Gy = P★Sobely
// y方向卷积运算的实现
//---------------------------------------------------
// Y
MAC_3 y0 (
  .aclr3(!iRST_N),
  .clock0(iCLK),
  .dataa_0(Line0),
  .datab_0(Y9),
  .datab_1(Y8),
  .datab_2(Y7),
  .result(Mac_y0)
);

MAC_3 y1 (
  .aclr3(!iRST_N),
  .clock0(iCLK),
  .dataa_0(Line1),
  .datab_0(Y6),
  .datab_1(Y5),
  .datab_2(Y4),
  .result(Mac_y1)
);

MAC_3 y2 (
  .aclr3(!iRST_N),
  .clock0(iCLK),
  .dataa_0(Line2),
  .datab_0(Y3),
  .datab_1(Y2),
  .datab_2(Y1),
  .result(Mac_y2)
);
PA_3 pa1 (
  .clock(iCLK),
  .data0x(Mac_y0),
  .data1x(Mac_y1),
  .data2x(Mac_y2),
  .result(Pa_y)
);
//-----------------------------------------------
// 得到G
//-----------------------------------------------
SQRT sqrt0 (
  .clk(iCLK),
  .radical(Pa_x * Pa_x + Pa_y * Pa_y),
  .q(Abs_mag)
);
//-------------------------------------------------
// 阈值比较
//-------------------------------------------------
always@(posedge iCLK, negedge iRST_N) begin
  if (!iRST_N)
    oDVAL <= 0;
  else begin
    oDVAL <= iDVAL;
    
    if (iDVAL)
      oDATA <= (Abs_mag > iTHRESHOLD) ? 0 : 1023;
    else
      oDATA <= 0;
  end
end

endmodule

IP设置
在这里插入图片描述
LineBuffer IP设置
在这里插入图片描述

LineBuffer IP的设置

在这里插入图片描述

MAC_3 IP的设置
在这里插入图片描述
PA_3 IP的设置
在这里插入图片描述
SQRT IP的设置
FPGA基于Sobel算子图像边缘检测的实现结果:
在这里插入图片描述
lena原图
在这里插入图片描述
阈值3
在这里插入图片描述
阈值5
在这里插入图片描述
阈值7

欢迎关注微信公众号:FPGA开源工作室
获取更多学习资料。
FPGA开源工作室

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