2019-10-16 20:22:15 weixin_43262648 阅读数 576

数字图像处理——Sobel算子锐化、Prewitt算子锐化

一、Sobel算子锐化

%函数名称为Image_Sobel,输入参数Image,输出参数IMAGE
function [IMAGE] = Image_Sobel(Image)
%获取矩阵的行、列、波段数
[m,n,bands] = size(Image);
%定义模板大小,假设模板大小3×3
A = 1;
%定义Sobel算子x,y方向矩阵
Sobelx = [-1 -2 -1;0 0 0;1 2 1];
Sobely = [-1 0 1;-2 0 2;-1 0 1];
%初始化矩阵
Image1 = zeros(m,n,bands);
IMAGE = Image;
%Sobel算子
for k = 1:bands
    for i = 1+A:m-A
        for j = 1+A:n-A
            temp = Image(i-A:i+A,j-A:j+A,k);
           	Image1(i,j,k) = abs(sum(sum(Sobelx.*temp)))+abs(sum(sum(Sobely.*temp)));
        end
    end
end
IMAGE = Image + Image1;
%画图,左右分别表示原图和两幅处理后的图像
figure(1);
subplot(1,3,1);
imshow(uint8(Image));
title('原始图像');
subplot(1,3,2);
imshow(uint8(Image1));
title('边缘提取图像');
subplot(1,3,3);
imshow(uint8(IMAGE));
title('Sobel算子锐化后的图像')
end

二、prewitt算子锐化

%函数名称为Image_Prewitt,输入参数Image,输出参数IMAGE
function [IMAGE] = Image_Prewitt(Image)
%获取矩阵的行、列、波段数
[m,n,bands] = size(Image);
%定义模板大小,假设模板大小3×3
A = 1;
%定义Prewitt算子x,y方向矩阵
Prewittx = [-1 -2 -1;0 0 0;1 2 1];
Prewitty = [-1 0 1;-2 0 2;-1 0 1];
%初始化矩阵
Image1 = zeros(m,n,bands);
IMAGE = Image;
%Sobel算子
for k = 1:bands
    for i = 1+A:m-A
        for j = 1+A:n-A
            temp = Image(i-A:i+A,j-A:j+A,k);
           	Image1(i,j,k) = abs(sum(sum(Prewittx.*temp)))+abs(sum(sum(Prewitty.*temp)));
        end
    end
end
IMAGE = Image + Image1;
%画图,左中右分别表示原图和两幅处理后的图像
figure(1);
subplot(1,3,1);
imshow(uint8(Image));
title('原始图像');
subplot(1,3,2);
imshow(uint8(Image1));
title('边缘提取图像');
subplot(1,3,3);
imshow(uint8(IMAGE));
title('Prewitt锐化后的图像')
end

调用方法

Image = double(imread('当前目录下的图片名称.jpg'));
Sobel = Image_Sobel(Image);
Prewitt = Image_Prewitt(Image);

在这里插入图片描述

在这里插入图片描述

2019-11-25 22:07:17 qq_43309286 阅读数 67

数字图像处理——拉普拉斯算子【像素级别处理】(python)

简介:

拉普拉斯算子是一种微分算子常在图像处理中强调灰度值的突变,不强调灰度变换缓慢的地方,得到的图层与原图像叠加在一起可以得到锐化的效果

一个二维图像的拉普拉斯算子可以定义为2f=2fx2+2fy2\nabla^{2}f=\frac{\partial^2 f}{\partial x^2}+\frac{\partial^2 f}{\partial y^2}

所以:
在X方向上存在2fx=f(x+1,y)+f(x1,y)2f(x,y)\frac{\partial^2 f}{\partial x}=f(x+1,y)+f(x-1,y)-2f(x,y)

在Y方向上存在2fy=f(x,y+1)+f(x,y1)2f(x,y)\frac{\partial^2 f}{\partial y}=f(x,y+1)+f(x,y-1)-2f(x,y)

可得:
2f=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)4f(x,y)\nabla^2f=f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)-4f(x,y)

扩展至对角线:
2f=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)+f(x1,y1)+f(x1,y+1)+f(x+1,y1)+f(x+1,y+1)8f(x,y)\nabla^2f=f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)+f(x-1,y-1)+f(x-1,y+1)+f(x+1,y-1)+f(x+1,y+1)-8f(x,y)

代码实现

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('Fig0338.tif')  # 测试图片
H = img.shape[0]
W = img.shape[1]

pixa = np.zeros((H, W), np.int32)
mImgae = np.zeros((H, W, 3), np.uint8)  # 标定(scale)前的滤波图像
smImga = np.zeros((H, W, 3), np.uint8)  # 标定(scale)后的滤波图像
pixb = np.zeros((H, W), np.int32)
mImgbe = np.zeros((H, W, 3), np.uint8)  # 标定前的滤波图像
smImgb = np.zeros((H, W, 3), np.uint8)  # 标定后的滤波图像
imga = np.zeros((H, W, 3), np.uint8)  # xy方向模板滤波后图像
imgb = np.zeros((H, W, 3), np.uint8)  # 加上对角方向模板滤波后图像

# a用到的算子是        b用到的算子是
# 0  1  0            1  1  1
# 1 -4  1            1 -8  1
# 0  1  0            1  1  1
# 先绘制标定滤波图像
# 标定指的是最小值设置为0,最大值设置为255的进行归一化的结果
for i in range(1, H - 1):
    for j in range(1, W - 1):
        pixa[i, j] = int(img[i - 1, j, 0]) + img[i + 1, j, 0] + img[i, j - 1, 0] + img[i, j + 1, 0] - 4 * int(
            img[i, j, 0])
        pixb[i, j] = int(img[i - 1, j - 1, 0]) + img[i - 1, j, 0] + img[i - 1, j + 1, 0] + img[i, j - 1, 0] + img[
            i, j + 1, 0] + img[i + 1, j - 1, 0] + img[i + 1, j, 0] + img[i + 1, j + 1, 0] - 8 * int(img[i, j, 0])

maxa = 0
maxb = 0
mina = 255
minb = 255

for i in range(H):
    for j in range(W):
        # 求出像素最大值和最小值,以利于scale
        if pixa[i, j] > maxa:
            maxa = pixa[i, j]
        if pixa[i, j] < mina:
            mina = pixa[i, j]
        if pixb[i, j] > maxb:
            maxb = pixb[i, j]
        if pixb[i, j] < minb:
            minb = pixb[i, j]
        if pixa[i, j] < 0:
            mImgae[i, j] = [0, 0, 0]
        else:
            mImgae[i, j, 0] = pixa[i, j]
            mImgae[i, j, 1] = pixa[i, j]
            mImgae[i, j, 2] = pixa[i, j]
        if pixb[i, j] < 0:
            mImgbe[i, j] = [0, 0, 0]
        else:
            mImgbe[i, j, 0] = pixb[i, j]
            mImgbe[i, j, 1] = pixb[i, j]
            mImgbe[i, j, 2] = pixb[i, j]

ka = 0
kb = 0
if maxa > mina:
    ka = 255 / (maxa - mina)
if maxb > minb:
    kb = 255 / (maxb - minb)

# scale处理
for i in range(H):
    for j in range(W):
        smImga[i, j, 0] = (pixa[i, j] - mina) * ka
        smImga[i, j, 1] = smImga[i, j, 0]
        smImga[i, j, 2] = smImga[i, j, 0]
        smImgb[i, j, 0] = (pixb[i, j] - minb) * kb
        smImgb[i, j, 1] = smImgb[i, j, 0]
        smImgb[i, j, 2] = smImgb[i, j, 0]

# 加上拉普拉斯算子
# pixa和pixb里面就是两个算子的结果
# lapa和lapb是原图加算子的结果,用来裁剪或者scale的原始数据
lapa = np.zeros((H, W), np.int32)
lapb = np.zeros((H, W), np.int32)

# 缩放处理
# maxa = 0
# maxb = 0
# mina = 255
# minb = 255

for i in range(H):
    for j in range(W):
        lapa[i, j] = img[i, j, 0] - pixa[i, j]
        lapb[i, j] = img[i, j, 0] - pixb[i, j]
        # 裁剪处理
        if lapa[i, j] > 255:
            lapa[i, j] = 255
        if lapa[i, j] < 0:
            lapa[i, j] = 0
        if lapb[i, j] > 255:
            lapb[i, j] = 255
        if lapb[i, j] < 0:
            lapb[i, j] = 0
        # 缩放处理
        # if lapa[i, j] > maxa:
        #     maxa = lapa[i, j]
        # if lapa[i, j] < mina:
        #     mina = lapa[i, j]
        # if lapb[i, j] > maxb:
        #     maxb = lapb[i, j]
        # if lapb[i, j] < minb:
        #     minb = lapb[i, j]

# 缩放处理
# ka = 0
# kb = 0
# if maxa > mina:
#     ka = 255 / maxa
# if maxb > minb:
#     kb = 255 / maxb

# scale处理
for i in range(H):
    for j in range(W):
        # 裁剪处理
        imga[i, j, 0] = lapa[i, j]
        imga[i, j, 1] = lapa[i, j]
        imga[i, j, 2] = lapa[i, j]
        imgb[i, j, 0] = lapb[i, j]
        imgb[i, j, 1] = lapb[i, j]
        imgb[i, j, 2] = lapb[i, j]
        # 缩放处理
        # if lapa[i, j] > 0:
        #     imga[i, j, 0] = lapa[i, j] * ka
        # else:
        #     imga[i, j, 0] = 0
        # imga[i, j, 1] = imga[i, j, 0]
        # imga[i, j, 2] = imga[i, j, 0]
        # if lapb[i, j] > 0:
        #     imgb[i, j, 0] = lapb[i, j] * kb
        # else:
        #     imgb[i, j, 0] = 0
        # imgb[i, j, 1] = imgb[i, j, 0]
        # imgb[i, j, 2] = imgb[i, j, 0]

# 原图
plt.subplot(1, 4, 1)
plt.axis('off')
plt.title('Original image')
plt.imshow(img)

# 图3.37a的模板
plt.subplot(2, 4, 2)
plt.axis('off')
plt.title('Before sale a')
plt.imshow(mImgae)

# scale后图3.37a的模板
plt.subplot(2, 4, 3)
plt.axis('off')
plt.title('After sale a')
plt.imshow(smImga)

# 图3.37a的模板锐化后的图像
plt.subplot(2, 4, 4)
plt.axis('off')
plt.title('Sharpened Image a')
plt.imshow(imga)

# 图3.37b的模板
plt.subplot(2, 4, 6)
plt.axis('off')
plt.title('Before sale b')
plt.imshow(mImgbe)

# scale后图3.37b的模板
plt.subplot(2, 4, 7)
plt.axis('off')
plt.title('After sale b')
plt.imshow(smImgb)

# 图3.37b的模板锐化后的图像
plt.subplot(2, 4, 8)
plt.axis('off')
plt.title('Sharpened Image b')
plt.imshow(imgb)

plt.show()

2019-01-17 18:04:44 qq_34814092 阅读数 245

Java OpenCV-4.0.0 图像处理13 Soble算子和Laplance算子

Java OpenCV-4.0.0 Soble算子和Laplance算子

package com.xu.opencv;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

/**  
 * 
 * @Title: Image.java   
 * @Description: OpenCV-4.0.0 测试文件
 * @Package com.xu.test   
 * @author: xuhyacinth     
 * @date: 2019年5月7日12:13:13   
 * @version: V-1.0.0 
 * @Copyright: 2019 xuhyacinth
 *
 */
public class Image {

	static {
		//在使用OpenCV前必须加载Core.NATIVE_LIBRARY_NAME类,否则会报错
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}

	public static void main(String[] args) {
		laplance();
	}

	/**
	 * OpenCV-4.0.0 Soble算子
	 * @return: void  
	 * @date: 2019年5月7日12:16:55
	 */
	public static void soble() {
		Mat src=Imgcodecs.imread("C:\\Users\\Administrator\\Pictures\\3.jpeg");
		Mat dst = new Mat();
		Mat gray= new Mat();
		//振幅图像(X、Y混合图像)
		//1 高斯平滑
		Imgproc.GaussianBlur(src, dst, new Size(3,3), 7,7);
		//2 转灰度图片
		Imgproc.cvtColor(dst, gray, Imgproc.COLOR_BGR2GRAY);
		//3 求X和Y的梯度
		Mat xgray = new Mat();
		Mat ygray = new Mat();
		//3.1 Sobel
		//Imgproc.Sobel(gray, xgray, Imgproc.CV_DIST_L2, 1, 0, 3);
		//Imgproc.Sobel(gray, ygray, Imgproc.CV_DIST_L2, 0, 1, 3);
		//3.2 Scharr
		Imgproc.Scharr(gray, xgray, Imgproc.CV_DIST_FAIR, 1, 0);
		Imgproc.Scharr(gray, ygray, Imgproc.CV_DIST_FAIR, 0, 1);
		//4.图像变为正数
		Core.convertScaleAbs(xgray, xgray);
		Core.convertScaleAbs(ygray, ygray);
		HighGui.imshow("Soble算子", xgray);
		HighGui.waitKey(0);
	}

	/**
	 * OpenCV-4.0.0 Laplance算子
	 * @return: void  
	 * @date: 2019年5月7日12:16:55
	 */
	public static void laplance () {
		Mat src=Imgcodecs.imread("C:\\Users\\Administrator\\Pictures\\3.jpeg");
		Mat gray= new Mat();
		Mat dst= new Mat();
		Mat image= new Mat();
		//1 高斯平滑
		Imgproc.GaussianBlur(src, dst, new Size(3,3), 7,7);
		//2 转灰度图片
		Imgproc.cvtColor(dst, gray, Imgproc.COLOR_BGR2GRAY);
		//3 Laplance算子
		Imgproc.Laplacian(gray, image, Imgproc.CV_CANNY_L2_GRADIENT,3);
		//Imgproc.threshold(image, image, 0, 255, Imgproc.THRESH_OTSU);
		HighGui.imshow("Laplance算子", image);
		HighGui.waitKey(0);
	}


}



Soble算子
Laplance算子

2016-03-14 21:32:15 jaych 阅读数 9496

sobel算子是什么

在图像处理上,算子一般也可以认为是滤波器,即filter,滤波器就是在一个像素点上对它进行与邻域之间的运算。

如中值滤波,就是在以像素点为中心,上下左右左上左下右上右下为邻域的集合里,如下图所示结构:

这里写图片描述

中值滤波就是对P1到P9进行排序,然后获取数值大小排在中间的值,把这个值当做该中心像素点P5的新值。

而sobel算子,是为了用来计算边缘的,一般而言,以3x3为大小,有下面这两种形式,Gx和Gy,Gx用来计算垂直边缘,Gy用来计算水平边缘。

通常混合使用,会有 |G| = |Gx| + |Gy|,绝对值用于消除梯度方向的影响。

这里写图片描述

如果按照上面P1到P9的排列,那么有:

Gx = |(P3+2P6+P9) - (P1+2P4+P7)|
Gy = |(P1+2P2+P3) - (P7+2P8+P9)|

这样的形式很好理解,假如中间为边缘,那么边缘两侧的亮度差距就会变大,乘以符号相反的系数,会使得最终的结果达到很大的值,在图像上来看就是白色;而不是边缘的区域,左右两边或者上下两边就会抵消,在图像上看就是黑色。

代码实现

这里比较简单就不赘述了。

主要是直接运用上面的算术关系,对每一个点进行换算。然后遍历整张图像就可以了。

后续在进行NEON优化时再做比较。

temp=abs(ptr[0]+2*ptr[1]+ptr[2]-(ptr[6]+2*ptr[7]+ptr[8]))+
abs(ptr[2]+2*ptr[5]+ptr[8]-(ptr[0]+2*ptr[3]+ptr[6]));


需要注意的是:在按照上述代码处理图像时,经sobel算子滤波之后,得到的图像与opencv中Sobel()函数得到的不一致。
经查看opencv源码,发现:主要是我们在处理时采用了abs()绝对值操作。而opencv是没有用绝对值,并且会对输出的图像做饱和处理,即大于255则输出为255,小于0则输出为0.

参考资料

http://homepages.inf.ed.ac.uk/rbf/HIPR2/sobel.htm

2013-09-03 23:28:21 kezunhai 阅读数 2928

          图像处理中,特征算子比较流行的现在已经不下上十种,而且关于图像特征算子的综述论文时有见刊。随着对图像处理及相关领域的进一步了解。一直就觉得有必要写一个关于图像处理中的特征算子的系列博文,来详细介绍这些算子的原理及其实现相关的内容。随着时间的推移,一直没有时间将这个工作付诸行动,不知不觉就毕业了。工作后,主要的工作内容还是和图像处理相关,而且发现工作中遇到的很多问题都可以从这些算子的设计思路中找到一些灵感,一定程度上助于问题的解决。遂,下定决心还是写一个关于特征算子系列吧。一来,当是对这些算子进一步的复习与理解;二来,希望能给正在学习图像处理路上的同学一些帮助;三来,也是为自己先前和现阶段的工作做一个小的总结。

         近年来,区分性强、对多种几何和光度变换具有不变性的局部不变特征在宽基线匹配、特定目标识别、目标类别识别、图像及视频检索、机器人导航、纹理识别和数据挖掘等多个领域内获得广泛的应用,是国内外的研究热点。

         局部不变特征是指局部特征的检测或描述对图像的各种变化,例如几何变换、光度变换、卷积变换、视角变化等保持不变。局部不变特征的基本思想是提取图像内容的本质属性特征,这些特征与图像内容的具体表现形式无关或具有自适应性(即表现形式变化时特征提取自适应的变化以描述相同的图像内容)。局部不变特征通常存在一个局部支撑邻域,与经典的图像分割算法不同,局部支撑邻域可能是图像的任何子集,支撑区域的边界不一定对应图像外观(例如颜色或纹理)的变化。

          局部不变特征的研究包含3个基本问题:一是局部不变特征的检测,二是局部不变特征的描述,三是局部不变特征的匹配。根据不同的准则,局部不变特征的研究方法可以分为不同的类别,按照使用的色调空间的不同可以分为局部灰度不变特征和局部彩色不变特征;按照特征层次的不同可以分为角点不变特征、blob不变特征和区域不变特征;按照几何变换不变性的自由度可以分为平移不变特征、旋转不变特征、尺度不变特征、欧氏不变特征、相似不变特征、仿射不变特征和投影不变特征;按照处理思路的不同可以分为基于轮廓曲率的不变特征、基于灰度梯度、灰度变化和显著性的不变特征,基于生物视觉启发的不变特征,基于多尺度的不变特征和基于分割的不变特征。

          局部不变特征应该具有以下特性:
          1)重复性(Repeatability) 
           相同场景或目标在不同成像条件下图像提取的局部不变特征应该是相同的;
          2)区分性 (Distinctiveness
           局部不变特征应包含较大的灰度或色度模式变化,易于区分;
          3)局部性(Locality
          局部不变特征应具有局部性,减小遮挡的概率,同时可以采用简单的变换模型对图像间的变换进行近似建模;
          4)精确性(Accuracy
          局部不变特征应可以在空域、尺度域及形状域上精确定位;
          5)不变性 (Invariant
          局部不变特征的检测和描述对各种变换应具有不变性;
          6)鲁棒性 (Robustness
           局部不变特征的检测和描述应对图像噪声、量化误差、模糊等不敏感。

欲了解更多特性,请参考:Tinne Turytelaars的论文:Local Invariant Feature Detectors 

          图像特征的研究最早可以追溯到1954年F.Attneave发表在Psychological Review的《some informational aspects of visual perception》,作者第一次观察到:形状信息集中在具有高曲率的主点(Dominant Points)上。经过近60年的发展,特征检测与提取算法得到了不断的丰富和突破。根据不同的分类,图像特征提取的方法可以分为不同的类别,主要包括基于轮廓曲率的方法(Contour Curvature Based Method)、基于灰度的方法(Intensity Based Methods,包括 海瑟矩阵方法(Hessian-Based Approach)、基于梯度方法(Gradient-Based Methods))、基于显著性的方法(Saliency Based Methods)、基于生物模拟的方法(Biologically Plausible Methods)、基于颜色的方法(Color Based Methods)、基于模型的方法(Model Based Methods)、多视角不变的方法(Toward Viewpoint Invariant Methods)、基于分割的方法(Segmentation Based Methods)以及基于机器学习的方法(machine learning based methods)等等。

          现今,在图像处理领域耳熟能详的特征算子包括:DoG、Fast、STAR、HARRIS、DENSE、SimpleBlob、MSER、SIFT、SURF、ORB、BRISK、FREAK等,本博文将逐一对这些算子进行分析。但可能由于工作原因,更新周期会比较长。今天写一个开篇,作为开始,也作为一个闹钟,提醒自己还有这个事没做。

         另外,有兴趣的朋友可以看看下列几篇文章,也可以通过链接下载:http://download.csdn.net/detail/kezunhai/6211147

          1)Keystian Mikolajczyk. A performance evaluation of local descriptors, 2005 PAMI

          2)Tinne Tuytelaars. Local Invariant Feature Detectors: A Survey, 2007 Computer Graphic & Vision

          3)王浩. 局部不变特征综述, 2011 计算机图像图像学报

          4) Umasankar Kandaswamy.  Comparison of Texture Analysis Schemes Under Nonideal Conditions,2011 IP

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