精华内容
下载资源
问答
  • Sobel算法

    2018-04-25 10:17:00
    最近看了一些Sobel算法,并试了一下,源码如下: private void Sobel(Bitmap img) { int width = img.Width; int height = img.Height; int[,] Gx = new int[3, 3]{ {-1, 0, 1 }, ...

    最近看了一些Sobel算法,并试了一下,源码如下:

    private void Sobel(Bitmap img) {
                int width = img.Width;
                int height = img.Height;
    
                int[,] Gx = new int[3, 3]{ {-1, 0, 1 },
                                           {-2, 0, 2 } ,
                                           {-1, 0, 1 } };
    
                int[,] Gy = new int[3, 3]{ {-1,-2,-1},
                                           { 0, 0, 0 },
                                           { 1, 2, 1}};
    
                int[,] TotalGx = new int[img.Width, img.Height];
                int[,] TotalGy = new int[img.Width, img.Height];
                int[,] GTotal = new int[img.Width, img.Height];
    
    
                Bitmap bitmapTemp = new Bitmap(img.Width, img.Height, PixelFormat.Format24bppRgb);
                
                LockBitmap lockBitmap1 = new LockBitmap(bitmapTemp);
                lockBitmap1.LockBits();
    
    
                LockBitmap lockBitmap = new LockBitmap(img);
                lockBitmap.LockBits();
                for (int i = 1; i < img.Width - 1; i++)
                {
                    for (int j = 1; j < img.Height - 1; j++)
                    {
                        Color a = lockBitmap.GetPixel(i - 1, j - 1);//[0][0]
                        Color b = lockBitmap.GetPixel(i - 1, j);    //[0][1]
                        Color c = lockBitmap.GetPixel(i - 1, j + 1);//[0][2]
                        
                        Color d = lockBitmap.GetPixel(i, j - 1);    //[1][0]
                        Color f = lockBitmap.GetPixel(i, j);        //[1][1]
                        Color g = lockBitmap.GetPixel(i, j + 1);    //[1][2]
    
                        Color h = lockBitmap.GetPixel(i + 1, j - 1);//[2][0]
                        Color l = lockBitmap.GetPixel(i + 1, j);    //[2][1]
                        Color n = lockBitmap.GetPixel(i + 1, j + 1); //[2][2]
    
    
                        TotalGx[i, j] = Gx[0, 0] * Avg(a) + Gx[0, 1] * Avg(b) + Gx[0, 2] * Avg(c)
                                       + Gx[1, 0] * Avg(d) + Gx[1, 1] * Avg(f) + Gx[1, 2] * Avg(g)
                                       + Gx[2, 0] * Avg(h) + Gx[2, 1] * Avg(l) + Gx[2, 2] * Avg(n);
    
    
    
    
                        //if (TotalGx[i, j] < 0) { TotalGx[i, j] = 0; }
                        //if (TotalGx[i, j] > 255) { TotalGx[i, j] = 255; }
    
                        TotalGy[i, j] = Gy[0, 0] * Avg(a) + Gy[0, 1] * Avg(b) + Gy[0, 2] * Avg(c)
                                      + Gy[1, 0] * Avg(d) + Gy[1, 1] * Avg(f) + Gy[1, 2] * Avg(g)
                                      + Gy[2, 0] * Avg(h) + Gy[2, 1] * Avg(l) + Gy[2, 2] * Avg(n);
    
    
                        //if (TotalGy[i, j] < 0) { TotalGy[i, j] = 0; }
                        //if (TotalGy[i, j] > 255) { TotalGy[i, j] = 255; }
    
    
    
                        //GTotal[i, j] = TotalGx[i, j] + TotalGy[i, j];
                        GTotal[i, j] = (int)Math.Sqrt(TotalGx[i, j] * TotalGx[i, j] + TotalGy[i, j] * TotalGy[i, j]);
    
                        if (GTotal[i, j] >= 255)
                        { GTotal[i, j] = 255; }
    
                        if (GTotal[i, j] < 0)
                        { GTotal[i, j] = 0; }
                        //bitmapTemp.SetPixel(i, j, Color.FromArgb(GTotal[i, j], GTotal[i ,j], GTotal[i, j]));
                        lockBitmap1.SetPixel(i, j, Color.FromArgb(GTotal[i, j], GTotal[i, j], GTotal[i, j]));
                    }
                }
                lockBitmap1.UnlockBits();
                lockBitmap.UnlockBits();
                pictureBox2.Image = lockBitmap1.GetBitmap();
    
            }

     

    public class LockBitmap
        {
            Bitmap source = null;
            IntPtr Iptr = IntPtr.Zero;
            BitmapData bitmapData = null;
    
            public byte[] Pixels { get; set; }
            public int Depth { get; private set; }
            public int Width { get; private set; }
            public int Height { get; private set; }
    
            public LockBitmap(Bitmap source)
            {
                this.source = source;
            }
    
            public Bitmap GetBitmap() { return this.source; }
    
            /// <summary>
            /// Lock bitmap data
            /// </summary>
            public void LockBits()
            {
                try
                {
                    // Get width and height of bitmap
                    Width = source.Width;
                    Height = source.Height;
    
                    // get total locked pixels count
                    int PixelCount = Width * Height;
    
                    // Create rectangle to lock
                    Rectangle rect = new Rectangle(0, 0, Width, Height);
    
                    // get source bitmap pixel format size
                    Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);
    
                    // Check if bpp (Bits Per Pixel) is 8, 24, or 32
                    if (Depth != 8 && Depth != 24 && Depth != 32)
                    {
                        throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");
                    }
    
                    // Lock bitmap and return bitmap data
                    bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,
                                                 source.PixelFormat);
    
                    // create byte array to copy pixel values
                    int step = Depth / 8;
                    Pixels = new byte[PixelCount * step];
                    Iptr = bitmapData.Scan0;
    
                    // Copy data from pointer to array
                    Marshal.Copy(Iptr, Pixels, 0, Pixels.Length);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
    
            /// <summary>
            /// Unlock bitmap data
            /// </summary>
            public void UnlockBits()
            {
                try
                {
                    // Copy data from byte array to pointer
                    Marshal.Copy(Pixels, 0, Iptr, Pixels.Length);
    
                    // Unlock bitmap data
                    source.UnlockBits(bitmapData);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            /// <summary>
            /// Get the color of the specified pixel
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public Color GetPixel(int x, int y)
            {
                Color clr = Color.Empty;
    
                // Get color components count
                int cCount = Depth / 8;
    
                // Get start index of the specified pixel
                int i = ((y * Width) + x) * cCount;
    
                if (i > Pixels.Length - cCount)
                    throw new IndexOutOfRangeException();
    
                if (Depth == 32) // For 32 bpp get Red, Green, Blue and Alpha
                {
                    byte b = Pixels[i];
                    byte g = Pixels[i + 1];
                    byte r = Pixels[i + 2];
                    byte a = Pixels[i + 3]; // a
                    clr = Color.FromArgb(a, r, g, b);
                }
                if (Depth == 24) // For 24 bpp get Red, Green and Blue
                {
                    byte b = Pixels[i];
                    byte g = Pixels[i + 1];
                    byte r = Pixels[i + 2];
                    clr = Color.FromArgb(r, g, b);
                }
                if (Depth == 8)
                // For 8 bpp get color value (Red, Green and Blue values are the same)
                {
                    byte c = Pixels[i];
                    clr = Color.FromArgb(c, c, c);
                }
                return clr;
            }
    
            /// <summary>
            /// Set the color of the specified pixel
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <param name="color"></param>
            public void SetPixel(int x, int y, Color color)
            {
                // Get color components count
                int cCount = Depth / 8;
    
                // Get start index of the specified pixel
                int i = ((y * Width) + x) * cCount;
    
                if (Depth == 32) // For 32 bpp set Red, Green, Blue and Alpha
                {
                    Pixels[i] = color.B;
                    Pixels[i + 1] = color.G;
                    Pixels[i + 2] = color.R;
                    Pixels[i + 3] = color.A;
                }
                if (Depth == 24) // For 24 bpp set Red, Green and Blue
                {
                    Pixels[i] = color.B;
                    Pixels[i + 1] = color.G;
                    Pixels[i + 2] = color.R;
                }
                if (Depth == 8)
                // For 8 bpp set color value (Red, Green and Blue values are the same)
                {
                    Pixels[i] = color.B;
                }
            }
    
            //public Color GetPixel(int x, int y)
            //{
            //    unsafe
            //    {
            //        byte* ptr = (byte*)Iptr;
            //        ptr = ptr + bitmapData.Stride * y;
            //        ptr += Depth * x / 8;
            //        Color c = Color.Empty;
            //        if (Depth == 32)
            //        {
            //            int a = ptr[3];
            //            int r = ptr[2];
            //            int g = ptr[1];
            //            int b = ptr[0];
            //            c = Color.FromArgb(a, r, g, b);
            //        }
            //        else if (Depth == 24)
            //        {
            //            int r = ptr[2];
            //            int g = ptr[1];
            //            int b = ptr[0];
            //            c = Color.FromArgb(r, g, b);
            //        }
            //        else if (Depth == 8)
            //        {
            //            int r = ptr[0];
            //            c = Color.FromArgb(r, r, r);
            //        }
            //        return c;
            //    }
            //}
    
            //public void SetPixel(int x, int y, Color c)
            //{
            //    unsafe
            //    {
            //        byte* ptr = (byte*)Iptr;
            //        ptr = ptr + bitmapData.Stride * y;
            //        ptr += Depth * x / 8;
            //        if (Depth == 32)
            //        {
            //            ptr[3] = c.A;
            //            ptr[2] = c.R;
            //            ptr[1] = c.G;
            //            ptr[0] = c.B;
            //        }
            //        else if (Depth == 24)
            //        {
            //            ptr[2] = c.R;
            //            ptr[1] = c.G;
            //            ptr[0] = c.B;
            //        }
            //        else if (Depth == 8)
            //        {
            //            ptr[2] = c.R;
            //            ptr[1] = c.G;
            //            ptr[0] = c.B;
            //        }
            //    }
            //}
    
    
    
            //return data[((width * y) + x) * 4 + i];
        }

    效果如下:

    总结:用自带的图片处理性能低下,建议使用指针或者其他图像库处理,比如OpenCV的.NET库。

     

    转载于:https://www.cnblogs.com/RainbowInTheSky/p/8940321.html

    展开全文
  • sobel算法

    千次阅读 2017-04-03 15:05:39
    本文代码来自sobel导数,该网站对opencv上图像处理的算法说明都很详细。如下: Sobel 导数 目标 本文档尝试解答如下问题: 如何使用OpenCV函数 Sobel 对图像求导。如何使用OpenCV函数 Scharr 更...

    本文代码来自sobel导数该网站对opencv上图像处理的算法说明都很详细。如下:

    Sobel 导数

    目标

    本文档尝试解答如下问题:

    • 如何使用OpenCV函数 Sobel 对图像求导。
    • 如何使用OpenCV函数 Scharr 更准确地计算 3 \times 3 核的导数。

    原理

    Note

     

    以下内容来自于Bradski和Kaehler的大作: Learning OpenCV .

    1. 上面两节我们已经学习了卷积操作。一个最重要的卷积运算就是导数的计算(或者近似计算).

    2. 为什么对图像进行求导是重要的呢? 假设我们需要检测图像中的 边缘 ,如下图:

      How intensity changes in an edge

      你可以看到在 边缘 ,相素值显著的 改变 了。表示这一 改变 的一个方法是使用 导数 。 梯度值的大变预示着图像中内容的显著变化。

    3. 用更加形象的图像来解释,假设我们有一张一维图形。下图中灰度值的”跃升”表示边缘的存在:

      Intensity Plot for an edge
    4. 使用一阶微分求导我们可以更加清晰的看到边缘”跃升”的存在(这里显示为高峰值)

      First derivative of Intensity - Plot for an edge
    5. 从上例中我们可以推论检测边缘可以通过定位梯度值大于邻域的相素的方法找到(或者推广到大于一个阀值).

    6. 更加详细的解释,请参考Bradski 和 Kaehler的 Learning OpenCV 。

    Sobel算子

    1. Sobel 算子是一个离散微分算子 (discrete differentiation operator)。 它用来计算图像灰度函数的近似梯度。
    2. Sobel 算子结合了高斯平滑和微分求导。

    计算

    假设被作用图像为 I:

    1. 在两个方向求导:

      1. 水平变化: 将 I 与一个奇数大小的内核 G_{x} 进行卷积。比如,当内核大小为3时, G_{x} 的计算结果为:

        G_{x} = \begin{bmatrix}-1 & 0 & +1  \\-2 & 0 & +2  \\-1 & 0 & +1\end{bmatrix} * I

      2. 垂直变化: 将:math:I 与一个奇数大小的内核 G_{y} 进行卷积。比如,当内核大小为3时, G_{y} 的计算结果为:

        G_{y} = \begin{bmatrix}-1 & -2 & -1  \\0 & 0 & 0  \\+1 & +2 & +1\end{bmatrix} * I

    2. 在图像的每一点,结合以上两个结果求出近似 梯度:

      G = \sqrt{ G_{x}^{2} + G_{y}^{2} }

      有时也用下面更简单公式代替:

      G = |G_{x}| + |G_{y}|

    Note

    当内核大小为 3 时, 以上Sobel内核可能产生比较明显的误差(毕竟,Sobel算子只是求取了导数的近似值)。 为解决这一问题,OpenCV提供了 Scharr 函数,但该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果却更加精确,其内核为:

    G_{x} = \begin{bmatrix}-3 & 0 & +3  \\-10 & 0 & +10  \\-3 & 0 & +3\end{bmatrix}G_{y} = \begin{bmatrix}-3 & -10 & -3  \\0 & 0 & 0  \\+3 & +10 & +3\end{bmatrix}

    关于( Scharr )的更多信息请参考OpenCV文档。在下面的示例代码中,你会发现在 Sobel 函数调用的上面有被注释掉的 Scharr 函数调用。 反注释Scharr调用 (当然也要相应的注释掉Sobel调用),看看该函数是如何工作的。

    解释

    1. 首先申明变量:

      Mat src, src_gray;
      Mat grad;
      char* window_name = "Sobel Demo - Simple Edge Detector";
      int scale = 1;
      int delta = 0;
      int ddepth = CV_16S;
      
    2. 装载原图像 src:

      src = imread( argv[1] );
      
      if( !src.data )
      { return -1; }
      
    3. 第一步对原图像使用 GaussianBlur 降噪 ( 内核大小 = 3 )

      GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );
      
    4. 将降噪后的图像转换为灰度图:

      cvtColor( src, src_gray, CV_RGB2GRAY );
      
    5. 第二步,在 x 和 y 方向分别”求导“。 为此,我们使用函数 Sobel :

      Mat grad_x, grad_y;
      Mat abs_grad_x, abs_grad_y;
      
      /// 求 X方向梯度
      Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
      /// 求 Y方向梯度
      Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
      

      该函数接受了以下参数:

      • src_gray: 在本例中为输入图像,元素类型 CV_8U
      • grad_x/grad_y: 输出图像.
      • ddepth: 输出图像的深度,设定为 CV_16S 避免外溢。
      • x_orderx 方向求导的阶数。
      • y_ordery 方向求导的阶数。
      • scaledelta 和 BORDER_DEFAULT: 使用默认值

      注意为了在 x 方向求导我们使用: x_{order}= 1 , y_{order} = 0. 采用同样方法在 y 方向求导。

    6. 将中间结果转换到 CV_8U:

      convertScaleAbs( grad_x, abs_grad_x );
      convertScaleAbs( grad_y, abs_grad_y );
      
    7. 将两个方向的梯度相加来求取近似 梯度 (注意这里没有准确的计算,但是对我们来讲已经足够了)。

      addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );
      
    8. 最后,显示结果:

      imshow( window_name, grad );
      

    结果

    1. 这里是将Sobel算子作用于 lena.jpg 的结果:

      Result of applying Sobel operator to lena.jpg

    翻译者

    niesu@ OpenCV中文网站 <sisongasg@hotmail.com>

    对译者致敬。

    这里放出它的代码,图片是我自己的test.jpg,输出我命名为testout.jpg

    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include <stdlib.h>
    #include <stdio.h>
    
    using namespace cv;
    
    /** @function main */
    int main()      //int argc, char** argv
    {
    
    	Mat src, src_gray;
    	Mat grad;
    	char* window_name = "Sobel Demo - Simple Edge Detector";
    	int scale = 1;
    	int delta = 0;
    	int ddepth = CV_16S;
    
    	//int c;
    
    	/// 装载图像
    	src = imread("test.jpg");
    
    	if (!src.data)
    	{
    		return -1;
    	}
    
    	GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT);
    
    	/// 转换为灰度图
    	cvtColor(src, src_gray, CV_RGB2GRAY);
    
    	/// 创建显示窗口
    	namedWindow(window_name, CV_WINDOW_AUTOSIZE);
    
    	/// 创建 grad_x 和 grad_y 矩阵
    	Mat grad_x, grad_y;
    	Mat abs_grad_x, abs_grad_y;
    
    	/// 求 X方向梯度
    	//Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
    	Sobel(src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);
    	convertScaleAbs(grad_x, abs_grad_x);
    
    	/// 求Y方向梯度
    	//Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
    	Sobel(src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT);
    	convertScaleAbs(grad_y, abs_grad_y);
    
    	/// 合并梯度(近似)
    	addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
    	imshow(window_name, grad);
    	imwrite("testout.jpg", grad);
    	waitKey(0);
    
    	return 0;
    }

        效果如下:



    展开全文
  • sobel算法FPGA实现

    2020-09-19 23:05:47
    sobel算法FPGA实现
  • sobel算法 opencv

    2016-10-25 15:56:42
    sobel算法 opencv
  • sobel算法介绍

    2012-02-21 11:24:03
    sobel算法介绍
  • 0引言  边缘检测技术是图像处理的一项基本技术,在工业、航天、医学、军事等领域中有着广泛的应用。边缘检测算法的实现涉及...在图1所示的3×3像素窗中,中间像素[i,j]为待检测像素,Sobel算法分别对此像素窗进行水
  • FPGA视频sobel算法实现

    2018-03-20 19:25:56
    FPGA,视频采集,sobel算法,在quartusII软件完美运行
  • sobel算法的硬件实现

    2018-12-27 15:46:52
    利用官方的视频处理库实现sobel算法的硬件实现,并通过了验证。 最后导出ip核,我把积分降成1分了,希望求个关注,蟹蟹!!!
  • 基于FPGA的Sobel算法.zip

    2021-01-04 09:02:09
    该资源是基于FPGA用Verilog实现的Sobel算法,一个ROM存储图片,另外两个RAM存储两行图像数据,代码量少,易于阅读和理解
  • 为提高图像边缘检测的处理速度,提出一种基于CORDIC的高速Sobel算法实现。在FPGA平台上,在并行处理数据和流水线操作的基础上,使用扩展数据位和覆盖所有角度的流水线型CORDIC,提高Sobel的运算效率。实验结果表明,...
  • Sobel算法的代码

    2013-05-08 11:56:54
    数字图像中图像的边缘提取,sobel算法的代码,以及处理图像效果。
  • 0引言  边缘检测技术是图像处理的一项基本技术,在工业、航天、医学、军事等领域中有着广泛的应用。边缘检测算法的实现涉及...在图1所示的3×3像素窗中,中间像素[i,j]为待检测像素,Sobel算法分别对此像素窗进行水
  • 本项目是使用Xilinx的ISE开发工具建立的工程,代码规范、可移植性强,保证下载者可以实现...该工程并不只是Sobel核心算法的验证,而是通过串口发送Matlab处理后的图像数据,经过Sobel算法后在VGA上显示效果的真实应用。
  • 首先先在这里,介绍一下Sobel算法的原理,以及实现过程,由于Sobel算法并不复杂,可以说是相对简单的,就不作过多的介绍. 先求x,y方向的梯度dx,dy 然后求出近似梯度G=dx2+dy2G = dx^{2}+dy^{2}G=dx2+dy2然后开根号...

    一. Sobel算法

    首先先在这里,介绍一下Sobel算法的原理,以及实现过程,由于Sobel算法并不复杂,可以说是相对简单的,就不作过多的介绍.

    1. 先求x,y方向的梯度dx,dy
    2. 然后求出近似梯度G=dx2+dy2G = dx^{2}+dy^{2}然后开根号,也可以为了分别计算近似为G=dx+dyG = |dx|+|dy|
    3. 最后根据G的值,来判断该点是不是边缘点,是的话,就将该点的像素复制为255,否则为0,,当然0或255可以自己随意指定,也可以是其他两个易于区分的像素值。

    二. dx,dy的求法

    • dx方向的核值如下,核值与图像上3*3的区域对应相乘然后相加,在这里插入图片描述

    • dy同dx求法一样在这里插入图片描述

    • 最后判断对应图像3*3区域的中心点是否为边缘点

    • 当然核值的1,2是可以修改的,例如3,10


    上面就简单的介绍了一下Sobel算法的原理以及实现步骤,接下来就在FPGA中实现它吧。

    三. 目标图片的准备

    我们先将图片写入rom中,然后将数据从rom中读出进行处理。
    先借助python和opencv将图片转为灰度图,然后生成mif文件,代码如下

    import numpy as np
    import matplotlib.pyplot as plt
    import os
    import shutil
    import cv2
    headfile = '''
    DEPTH = 10000;
    WIDTH = 8;
    ADDRESS_RADIX = HEX;
    DATA_RADIX = HEX;
    CONTENT
    BEGIN
    '''
    img = cv2.imread("13.png")     #读取图片
    img = cv2.resize(img,(100,100))  #将图片resize到100*1001的大小
    img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)		#将图片转为灰度图
    mif = open('image.mif', 'w')
    mif.writelines(headfile)
    i = 0
    for m in range(0,100):
        for n in range(0,100):
            mif.writelines(str(hex(i)[2:]))
            mif.writelines(' : ')
            mif.writelines(str(hex(img[m][n]))[2:])# + str(hex(img[n][m][1]))[2:] + str(hex(img[n][m][0]))[2:])
            mif.writelines(';')
            mif.writelines('\n')
            i += 1
    mif.write('END;')
    

    经过上面的代码,就可以生成mif文件了,然后在软件中调用单端rom的ip,并且选择mif就可以了,位宽8,深度10000。


    根据我们的dx,dy的核值,可以看出,每一次操作需要三行图像数据,
    以及每一行图像数据的三个连续的值。
    所以我们需要两个ram来存储两行数据,另外一行为当前读取的数据,
    不需要事先存储,连续的三个值可以用延时
    

    四. 两行图像数据的存储

    先事先声明一下如下数据

    reg[7:0]	data_line_11,data_line_12,data_line_13;		#第一行数据的3个值
    reg[7:0]	data_line_21,data_line_22,data_line_23;		#第二行数据的3个值
    reg[7:0]	data_line_31,data_line_32,data_line_33;		#第三行数据的3个值
    

    采用双端ram,进行存储数据,由于图像的宽度为100,所以深度为128即可。
    实例出来代码如下

    RAM RAM_V1(
    	.clock(clk_9M),				//时钟
    	.data(ram1_data_in),		//写入的数据
    	.rdaddress(ram1_raddr),	//读出的地址
    	.wraddress(ram1_waddr),	//写入的地址
    	.wren(1'b1),					//读写使能
    	.q(ram1_data_out));	//读出的数据
    	
    RAM RAM_V2(
    	.clock(clk_9M),
    	.data(ram2_data_in),
    	.rdaddress(ram2_raddr),
    	.wraddress(ram2_waddr),
    	.wren(1'b1),
    	.q(ram2_data_out));
    

    为了使最边缘的图像数据建立起3*3的区域,这里将图像的最框添加了0像素值,所以现在处理的图像数据大小为102 * 102了。

    1. 假定一二行数据以及存储进去了,现在读取的是第三行。

       当第三行读取到第三个数据时,是不是可以将第二行的数据的第一个更新为
       第三行读取到第一个数据,将第一行的数据的第一个更新为第二行数据的第一个
       同样当第三行数据读到第四,五,六...个数据时,依次更新第一行第二行的第二,
       三,四...个数据
      
    2. 假定第一行,第二行没有数据,当为显示到图像的第一行时,将第一行的数据写入0,然后按照1的方式更新第二行数据。

    //图像显示的区域 cur_x >= 'd101 && cur_x <='d200 && 
    //				cur_y >= 'd50 && cur_y < 'd150
    //第一行 写
    always@(posedge clk_9M or negedge rst)
    begin
    	if(rst == 1'b0)
    		ram1_waddr <= 'd0;
    	else if(cur_x >= 'd100 && cur_x <= 'd201 && cur_y >= 'd49)
    		ram1_waddr <= ram1_waddr + 1'b1;
    	else
    		ram1_waddr <= 'd0;
    end
    always@(posedge clk_9M or negedge rst)
    begin
    	if(rst == 1'b0)
    		ram1_data_in <= 'd0;
    	else if(cur_x >= 'd100 && cur_x <= 'd201 && cur_y >= 'd49)
    		if(cur_y == 'd49)
    			ram1_data_in <= 'd0;
    		else
    			ram1_data_in <= data_line_21;
    end
    
    
    //第二行 写
    always@(posedge clk_9M or negedge rst)
    begin
    	if(rst == 1'b0)
    		ram2_waddr <= 'd0;
    	else if(cur_x >= 'd100 && cur_x <= 'd201 && cur_y >= 'd49)
    		ram2_waddr <= ram2_waddr + 1'b1;
    	else
    		ram2_waddr <= 'd0;
    end
    always@(posedge clk_9M or negedge rst)
    begin
    	if(rst == 1'b0)
    		ram2_data_in <= 'd0;
    	else if(cur_x >= 'd100 && cur_x <= 'd201 && cur_y >= 'd49)
    		ram2_data_in <= data_line_31;
    end
    
    

    五. 三行数据的读取

    这个较为简单了,直接从对应的rom和ram中读出即可
    下面代码是第二行和第三行的,第一行就不拿出来了,都一模一样的。

    always@(posedge clk_9M or negedge rst)
    begin
    	if(rst == 1'b0)
    		begin
    			data_line_21 = 'd0;
    			data_line_22 = 'd0;
    			data_line_23 = 'd0;
    		end
    	//这里读取的cur_x的值对比于显示的值需要注意一下
    	else if(cur_x >= 'd98 && cur_x <= 'd199 && cur_y >= 'd50) 
    		begin
    			data_line_21 <= data_line_22;
    			data_line_22 <= data_line_23;
    			data_line_23 <= ram2_data_out;		
    		end
    	else
    		begin
    			data_line_21 <= data_line_22;
    			data_line_22 <= data_line_23;
    			data_line_23 <= 'd0;	
    		end
    end
    always@(posedge clk_9M or negedge rst)
    begin
    	if(rst == 1'b0)
    		begin
    			data_line_31 <= 'd0;
    			data_line_32 <= 'd0;
    			data_line_33 <= 'd0;
    		end
    	else if(cur_x >= 'd98 && cur_x <= 'd199 && cur_y >= 'd49 && cur_y < 149)
    		begin
    			data_line_33 <= img;
    			data_line_32 <= data_line_33;
    			data_line_31 <= data_line_32;
    		end
    	else
    		begin
    			data_line_31 <= data_line_32;
    			data_line_32 <= data_line_33;
    			data_line_33 <= 'd0;
    		end
    end
    

    六. 进行Sobel运算

    这里需要注意一下dx和dy的值可能会有1000多,所以说其位宽不在是8了而是10.

    分别计算负的和正的,然后判断大小,最近用大的减去小的。最后与阈值进行判断来赋值。 阈值的大小不是0-255了,而是0-1520(肯能不太准确),我下面的是1035.

    reg[10:0]	Sobel_px ,Sobel_nx;
    reg[10:0]	Sobel_py ,Sobel_ny;
    
    wire[10:0]	Sobel_x;
    wire[10:0]	Sobel_y;
    
    wire[7:0]	Sobel_data;
    
    
    assign Sobel_x = (Sobel_px > Sobel_nx) ? (Sobel_px - Sobel_nx) : (Sobel_nx - Sobel_px);
    assign Sobel_y = (Sobel_py > Sobel_ny) ? (Sobel_py - Sobel_ny) : (Sobel_ny - Sobel_py);
    assign Sobel_data = (Sobel_x + Sobel_y > 'd1035) ? 'd0 : 'd255;
    
    
    
    always@(posedge clk_9M or negedge rst)
    begin
    	if(rst == 1'b0)
    		begin
    			Sobel_px <= 'd0;
    			Sobel_nx <= 'd0;
    		end
    	else if(cur_x >= 'd100 && cur_x <= 'd199 && cur_y >= 'd50)
    		begin
    			Sobel_nx <= data_line_11 + data_line_21 + data_line_21 + data_line_31;
    			Sobel_px <= data_line_13 + data_line_23 + data_line_23 + data_line_33;
    		end
    	else
    		begin
    		Sobel_nx <= 'd0;
    		Sobel_px <= 'd0;
    		end
    end
    
    
    always@(posedge clk_9M or negedge rst)
    begin
    	if(rst == 1'b0)
    		begin
    			Sobel_py <= 'd0;
    			Sobel_ny <= 'd0;
    		end
    	else if(cur_x >= 'd100 && cur_x <= 'd199 && cur_y >= 'd50)
    		begin
    			Sobel_py <= data_line_11 + data_line_12 + data_line_12 + data_line_13;
    			Sobel_ny <= data_line_31 + data_line_32 + data_line_32+ data_line_33;
    		end
    	else
    		begin
    			Sobel_ny <=	'd0;
    			Sobel_py <=	'd0;
    		end
    end
    

    最后给出在FPGA上的原图和效果图,效果不错,完整项目下载链接
    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • 边缘检测sobel算法

    2020-03-10 17:13:53
    边缘检测sobel算法: 原理:略(哈哈) MATLAB实现: clc; clear; imag = imread('1.jpg'); %读取关键帧 imag = rgb2gray(imag); %转化为灰度图 figure,imshow(imag); title('原图'); gx = [-1 -2 -1;0 0 0;1 2 ...

    边缘检测sobel算法:


    原理:略(哈哈)











    MATLAB实现:
    clc;
    clear;
    imag = imread('1.jpg');  %读取关键帧
    imag = rgb2gray(imag);        %转化为灰度图
    figure,imshow(imag);
    title('原图'); 
    gx = [-1 -2 -1;0 0 0;1 2 1];
    gy = [-1 0 1;-2 0 2;-1 0 1];
    [high,width] = size(imag);   % 获得图像的高度和宽度      
    imag1 = double(imag);
    uSobel = zeros(high,width);
    for i = 2:high - 1   %sobel边缘检测
        for j = 2:width - 1
            Gx = sum(sum(gx.*imag1(i-1:i+1, j-1:j+1))); %先求行和,再求列和
            Gy = sum(sum(gy.*imag1(i-1:i+1, j-1:j+1)));
            uSobel(i,j) = sqrt(Gx^2 + Gy^2); 
        end
    end 
    uSobel=mat2gray(uSobel);%将matrix值映射到[0,1],归一化
    figure,imshow(uSobel);
    title('边缘检测后');  %画出边缘检测后的图像
    % Matlab自带函数边缘检测
    % K为获取得到的关键帧的灰度图
    BW3 = edge(imag,'sobel', 0.09);
    figure,imshow(BW3,[]);
    title('Matlab自带函数边缘检测');
    
    
    展开全文
  • sobel算法C++实现

    热门讨论 2009-06-30 20:20:36
    这个好像没什么可以说的 sobel算法实现,另外还附带了opencv的配置文档
  • 基于FPGA的sobel算法仿真验证,利用modelsim验证算法,简单的matlab生成数据和还原数据,最终生成图片对比结果,符合预期要求
  • 利用openGL实现的sobel算法,vs2013下编译,可以看看参考参考
  • 基于FPGA边缘识别算法的Verilog代码实现 灰度值转换 3*3矩阵生成 Sobel算法实现 ,详细讲解可参考本人博客本文链接:https://blog.csdn.net/weixin_44580647/article/details/106658899。本工程在Quartus13.0 编写 ...
  • 基于FPGA的Sobel算法实现

    千次阅读 2019-01-01 19:04:10
    基于FPGA的Sobel算法实现 第一次写这种技术博客,发现整理清楚思路,把想法清楚的表达出来还是挺困难的。在努力表达清楚的过程中,发现觉得逻辑不太清晰的原因可能是自己的理解根本就没有深入。这篇博文是自己2019年...
  • 本文偏重于算法原理的理解及C语言编程实现,更详细的原理简介,可以参考网上其他文章 ...所以本文记录一下sobel算法的实现,并探讨用于canny算法的sobel和OpenCV输出的标准的sobel之间的差异 二 代码 ...
  • 基于FPGA的图像边缘检测Sobel算法的研究与实现.pdf
  • 照着书中的样例实现了sobel算法: 1.结合opencv读取图像,保存到缓冲区中。 2.编写和编译内核。并保存显示处理后的结果。 内核: const sampler_t sampler = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; ...
  • sobel算法边缘检测 小梅哥书上的教程讲得很好 《小梅哥-FPGA系统设计与验证实战指南_V24》P836 7.11 sobel算法做边缘检测其实也可以用作一种二值化操作 简单定义:卷积是分析数学中一种重要的运算。 设:f(x),g(x)是...
  • 算法系列:基于 FPGA 的图像边缘检测系统设计(sobel算法) 今天给大侠带来基于 FPGA 的图像边缘检测设计,话不多说,上货。 设计流程如下: mif文件的制作→ 调用ip核生成rom以及仿真注意问题→ 灰度处理→ 均值...
  • Sobel算法原理及代码(python2.7)

    千次阅读 2018-07-17 16:00:39
    Sobel算法原理及代码(python2.7) sobel算子针对被检测点,在像素点灰度计算过程中,考虑到了像素点3*3领域上的8个方向的像素点,并将所有点的灰度值进行加权差,并根据加权差的结果来确定被检测点的灰度值。 ...
  • sobel算法的HLS实现.rar

    2021-04-18 10:53:36
    sobel 边缘检测HLS实现
  • OpenCV图像边缘检测(sobel算法

    千次阅读 2017-07-08 10:39:52
    一、sobel算法简介   索贝尔算子(Sobel operator)主要用作边缘检测,它是一离散性差分算子,它结合了高斯平滑和微分求导,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的...
  • Sobel算法实现(C语言)

    千次阅读 2012-12-13 10:56:40
    Sobel算法实现(C语言) 1 void MySobel(IplImage* gray, IplImage* gradient)  2 {  3 /* Sobel template  4 a00 a01 a02  5 a10 a11 a12  6 a20 a21 a22  7 */  8  9 unsigned ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,305
精华内容 522
关键字:

sobel算法