精华内容
下载资源
问答
  • 拉普拉斯的图片
    千次阅读
    2019-12-27 13:19:37

    一. 模糊图像评价基础知识

    图像质量评价(IQA),根据参考图片(reference image),即原始图片的存在与否,可分为:

    • 全参考(full-reference)方法, 有原始图片的全部信息
    • 半参考(reduced-reference)方法, 只有原始图片的部分信息
    • 无参考(no-reference)方法,没有原始图片

    模糊图片分类

    • defocus blur image 散焦模糊图像
    • motion blur image 运动模糊图像

    图像模糊原因:

    • 确定性因素:包括成像系统调焦不当、目标物体相对运动等
    • 随机性因素:主要是图像在记录、传输过程中的污染,比如电子系统的高频性能不好造成图像高频分量的损失。

    在频域,当一幅图像的高频部分被削弱时图像看起来会显得模糊。

    在空域,图像的边界和细节部分不清晰时,图像看起来也会显得模糊。

    二. 无参考图片算法实现(Python)

    import cv2
    import os
    import time
    
    class Laplacian :
        def __init__(self, image_dir, recursion = False) :
            self.__image_dir = image_dir
            self.__image_paths = []
            for root_dir, sub_dirs, images in os.walk(image_dir, recursion) :
                for image in images :
                    self.__image_paths.append(os.path.join(root_dir, image))
    
        def __read_image(self, image_path) :
            # In the case of color images, the decoded images will have the channels stored in **B G R** order.
            # When using IMREAD_GRAYSCALE, the codec's internal grayscale conversion will be used, if available.
            # Results may differ to the output of cvtColor()
            return cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    
        def __pre_process_image(self, image_path, **kwargs) :
            image = self.__read_image(image_path)
            if kwargs.get('width') and kwargs.get('height') :
                image = cv2.resize(image, (kwargs.get('width'), kwargs.get('height')))
            return image
    
        def get_image_paths(self) :
            return self.__image_paths
    
        def blur_detect(self, image_path) :
            cv_image = self.__pre_process_image(image_path, width = 200, height = 200)
            return cv2.Laplacian(cv_image, cv2.CV_64F).var()
    
    
    def test_laplacian() :
        laplacian = Laplacian('dir of images that you want to detect with laplacian', False)
        image_paths = laplacian.get_image_paths()
        for path in image_paths :
            begin = time.time() * 1000
            score = laplacian.blur_detect(path)
            end = time.time() * 1000
            print("Laplacian detection {} value is {}, cost time {} ms".format(path, int(score), end - begin))
    
    
    if __name__ == "__main__" :
        test_laplacian()
    
    

    代码核心是OpenCV提供的接口cv2.Laplacian

    def Laplacian(src, ddepth, dst=None, ksize=None, scale=None, delta=None, borderType=None):
    “”"
    Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]]) -> dst
    . @brief Calculates the Laplacian of an image.
    .
    . The function calculates the Laplacian of the source image by adding up the second x and y
    . derivatives calculated using the Sobel operator:
    .
    . \f[\texttt{dst} = \Delta \texttt{src} = \frac{\partial^2 \texttt{src}}{\partial x^2} + \frac{\partial^2 \texttt{src}}{\partial y^2}\f]
    .
    . This is done when ksize > 1. When ksize == 1, the Laplacian is computed by filtering the image
    . with the following \fKaTeX parse error: Undefined control sequence: \f at position 11: 3 \times 3\̲f̲ aperture:
    .
    . \f[\vecthreethree {0}{1}{0}{1}{-4}{1}{0}{1}{0}\f]
    .
    . @param src Source image.
    . @param dst Destination image of the same size and the same number of channels as src .
    . @param ddepth Desired depth of the destination image.
    . @param ksize Aperture size used to compute the second-derivative filters. See #getDerivKernels for
    . details. The size must be positive and odd.
    . @param scale Optional scale factor for the computed Laplacian values. By default, no scaling is
    . applied. See #getDerivKernels for details.
    . @param delta Optional delta value that is added to the results prior to storing them in dst .
    . @param borderType Pixel extrapolation method, see #BorderTypes
    . @sa Sobel, Scharr
    “”"
    pass

    可以在__pre_process_image中进行图像的预处理,统一图像尺寸,类似于归一化的作用。

    三. 算法评价

    尝试用这个算法用于人脸识别的预处理步骤,判断人脸图片是否模糊。实际测试结果来看,单用拉普拉斯算子进行卷积运算,无法很好的评价人脸是否模糊。

    目前从我测试的情况看,下面两篇参考文章提到的基于二次模糊的清晰度算法(ReBlur) 比较推荐使用。

    1. 面向无参考图像的清晰度评价方法研究
    2. The Blur Effect: Perception and Estimation with a New No-Reference Perceptual Blur Metric
    更多相关内容
  • 拉普拉斯图片融合.zip

    2020-05-30 16:03:57
    救救孩子吧,想下资源没有积分,手头宽裕的大佬赏我点积分。想要资源没积分的可以私我,也发给你。对了,文件需要配置OpenCV的环境,环境的话官网就有那个OpenCV的exe执行文件,配一下就能用,源码是cpp文件的源码,...
  • 可实现图片的读入,以及进行拉普拉斯滤波,canner滤波等
  • 显示的图片下采样尺寸是不断减小的,上采样反之。 我把画布固定了尺寸,所以看起来是一样的长宽。 0函数 #导入库 import cv2 import numpy as np import matplotlib.pyplot as plt from PIL import Image #用于...

    显示的图片下采样尺寸是不断减小的,上采样反之。 我把画布固定了尺寸,所以看起来是一样的长宽。

    0函数

    #导入库
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    from PIL import Image 
    
    #用于打印函数
    def out_img(img):
        plt.figure(figsize=(10,10)) #设置窗口大小
        dst_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        plt.subplot(1,1,1),
        plt.imshow(dst_img),
        plt.axis('off')
        return
    
    #构建高斯金字塔 levle为下采样次数
    def get_gauss_pyr(img,level):
        gs_pic = img.copy()#原图
        gauss_list = [gs_pic] 
        for i in np.arange(4):  
            print(i)
            gs_pic = cv2.pyrDown(gs_pic)
            out_img(gs_pic)
            gauss_list.append(gs_pic)
        return gauss_list 
    
    #构建拉普拉斯金字塔
    #lpls_list是用于保存拉普拉斯特征的列表       它在  创建的时候先添加了 gauss 最小尺度图片作为第#一个元素
    #gs_list 高斯金字塔 list
    #函数返回的list 包含 高斯最下尺度图片 + 拉普拉斯各层级图片
    def get_lpls_pyr(lpls_list, gs_list):
        dis = len(gs_list)-1
        print("dis is :", dis)
        for i in np.arange(dis, 0,-1):   
            print(i)
            GE = cv2.pyrUp(gs_list[i])
            L = cv2.subtract(np.array(gs_list[i-1]),np.array(GE))
            out_img(L)
            lpls_list.append(L)
        return lpls_list
    
    #图片融合 将两个图片的拉普拉斯list 各层级拼接到一起
    def get_added_lpls(lpls_a, lpls_b):
        LS = []
        for la,lb in zip(lpls_a,lpls_b):
            rows,cols,dpt = la.shape
            ls = np.hstack((la[:,0:int(cols/2)], lb[:,int(cols/2):]))    
            out_img(ls)
            print(ls.shape)
            LS.append(ls)
        return LS
    
    #还原融合后的图片
    #ls_ = LS[0] 是指最下尺度的高斯特征图片 之后把其不断上采样并与 对应尺度的拉普拉斯特征(added)融合 
    def get_added_pic(LS):
        ls_ = LS[0]   
        for i in range(1,len(LS)):                        
            ls_ = cv2.pyrUp(ls_)
            ls_ = cv2.add(ls_, LS[i])                
            out_img(ls_)
        return ls_

    1高斯金字塔下采样

    这里进行了4次的下采样。所有原图的长宽需要能整除16(即2*2*2*2四次)。

    如果不能整除16 会怎么样?

    假如 原图尺寸 100*100 那么四次下采样就会变成 50* 50-> 25*25 -> 12*12 -> 6*6

    在我们后续还原图片的时候 , 使用cv2.pyrUp 来对12*12  尺度的图片进行上采样的时候会得到 24*24 尺度的图片,不等于原来的

    25*25。 之后需要与原来的25*25尺度图片相加 这里尺度不相等,相加会报错。

    第一张图片构建高斯金字塔 四次下采样:

    第二张图片构建高斯金字塔 四次下采样:

    2构建拉普拉斯金字塔

    第一张图片构建拉普拉斯金字塔 :

    第二张图片构建拉普拉斯金字塔 :

    3拉普拉斯金字塔拼接(融合)

    最小高斯金字塔尺度图片的拼接

     拉普拉斯金字塔各层次的拼接

    4还原融合后的图片

     

     

     

    5与直接拼接对比

    real = np.hstack((A[:,:cols//2],B[:,cols//2:]))   
    out_img(real)
    cv2.imwrite('Direct_blending.jpg',real)

     

    看融合边界的区别  拉普拉斯金字塔方法 是相融感觉的拼接 。

     直接融合 的边界很割裂。

    6代码 (非函数版本) 比较好理解吧

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    from PIL import Image 
    
    def out_img(img):
        plt.figure(figsize=(10,10)) #设置窗口大小
        dst_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        plt.subplot(1,1,1),
        plt.imshow(dst_img),
        plt.axis('off')
        return
    
    A = cv2.imread('bk2.jpg')
    B = cv2.imread('bk1.jpg')
    h, w, c = A.shape 
    A = cv2.resize(A,(448,448))
    B = cv2.resize(B,(448,448))
    print(A.shape, B.shape)
    
    # 在A图上构建高斯金字塔 
    
    G = A.copy()
    gpA = [G]
    for i in np.arange(4):     
        G = cv2.pyrDown(G)
        out_img(G)
        gpA.append(G)
    
    # 在B图像上构建高斯金字塔
    
    G = B.copy()
    gpB = [G]
    for i in np.arange(4):  
        G = cv2.pyrDown(G)
        out_img(G)
        gpB.append(G)
    
    lpA = [gpA[-1]]
    lpB = [gpB[-1]]
    
    # 构建A图像的拉普拉斯金字塔
    for i in np.arange(4,0,-1):   
        GE = cv2.pyrUp(gpA[i])
        L = cv2.subtract(np.array(gpA[i-1]),np.array(GE))
        out_img(L)
        lpA.append(L)
    
    # 构建B图像的拉普拉斯金字塔
    for i in np.arange(4,0,-1):    
        GE = cv2.pyrUp(gpB[i])
    #     out_img(GE)
        L = cv2.subtract(gpB[i-1],GE)
        out_img(L)
        lpB.append(L)
    
    LS = []
    for la,lb in zip(lpA,lpB):
        rows,cols,dpt = la.shape
        ls = np.hstack((la[:,0:int(cols/2)], lb[:,int(cols/2):]))    
        out_img(ls)
        print(ls.shape)
        LS.append(ls)
    
    ls_ = LS[0]   
    for i in range(1,len(LS)):                        
        ls_ = cv2.pyrUp(ls_)
        ls_ = cv2.add(ls_, LS[i])                
        out_img(ls_)
    cv2.imwrite('lpls_added.jpg',ls)
    
    real = np.hstack((A[:,:cols//2],B[:,cols//2:]))   
    out_img(real)
    cv2.imwrite('Direct_added.jpg',real)

     

    展开全文
  • 简单图像融合(加权平均、像素选大、像素选小)算法,拉普拉斯金字塔算法的Matlab实现 GUI界面 简单图像融合(加权平均、像素选大、像素选小)算法,拉普拉斯金字塔算法的Matlab实现 GUI界面
  • 中值滤波器是一种非线性数字滤波技术,常用于通过拉普拉斯分布去除噪声。 中值滤波器的主要思想是逐个条目遍历信号条目,用相邻条目的中值替换每个条目。 邻居的模式称为“窗口”,它在整个信号上逐项滑动。
  • edge_detect.m : 图像边缘检测 其中使用 梯度算子边缘检测 : roberts算子、...二阶微分算子法 : 拉普拉斯高斯算子、canny算子 lenna.bmp : 原始灰度图片 实验结果文件夹 : 保存了实验过程中生成的图像和程序流程图
  • 计算图像sobel、prewitt、roberts算子,canny 高斯-拉普拉斯算子,进行并交差、镜像等操作。包含示例图片
  • 比较空域内不包含对角线邻域的laplacian算子增强和包括对角线邻域的laplacian算子增强图像效果的区别。
  • iOS快速利用拉普拉斯算子做图片锐化滤镜
  • 拉普拉斯算子用于图像锐化处理-拉普拉斯算子用于图像锐化处理.doc 用Matlab拉普拉斯算子 处理图像,达到锐化边缘的效果 含有Matlab程序及相关图片
  • 拉普拉斯方差算法(Variance of the Laplacian) 图1,用拉普拉斯算子与输入图像做卷积 我检测图片模糊量的第一步就是去拜读这篇优秀的综述文献——《Analysis of focus measure operators for shape-from-focus》...

    在刚刚过去的这个周末,我坐下来想在 iphoto 中整理这些海量的照片。这不仅仅意味着巨大的工作量,因为我很快注意到一个现象——其中充斥着大量模糊的照片。

    主要因为我的摄影技术比较low,Jemma又特别活泼,跑来跑去,有时候看到我拍照,它又吓得缩起来发抖,所以我抓拍的效果不是很好,导致有多照片都是模糊的

    作为一个普通人,我可能会想软件设计者们会开发出新功能来检测出这些模糊的照片(或者至少把他们移到一个单独的文件夹)。但是作为一个计算机视觉科学家,我是不会这样想的。

    相反,我打开编辑器很快就编写了一个 Python 脚本,用 OpenCV 来执行模糊检测。

    在这篇文章剩下的部分里,我将会展示如何用 OpenCV、Python 和拉普拉斯算子来计算图片中的模糊量。到文章结束,读者就能应用拉普拉斯方差算法来检测图片中的模糊量。

    拉普拉斯方差算法(Variance of the Laplacian)

    1R95M916-0.jpg

    图1,用拉普拉斯算子与输入图像做卷积

    我检测图片模糊量的第一步就是去拜读这篇优秀的综述文献——《Analysis of focus measure operators for shape-from-focus》[2013 Pertuz et al.]。在这篇文献中,Pertuz 等人论述了近 36 种不同的图片清晰度评价(focus measure)方法。

    如果读者了解信号处理,就会知道最直接的方法就是计算图片的快速傅里叶变换,然后查看高低频的分布。如果图片有少量的高频成分,那么该图片就可以被认为是模糊的。然而,区分高频量多少的具体阈值却是十分困难的,不恰当的阈值将会导致极差的结果。

    相反,如果我们能用计算出的一个具体浮点数值来表征图片的模糊程度,岂不是十分优雅?

    Pertuz 等人讨论了很多种方法来计算“模糊度”。其中的一些方法简单明了,仅仅使用了像素灰度值的统计数据,其他的一些相比更加先进并且是基于特征的,使用了局部二值模式。

    在快速浏览论文之后,我开始着手实现我找到的拉普拉斯方差算法——出自  Pech-Pacheco 等人 2000 年模式识别国际会议论文:《Diatom autofocusing in brightfield microscopy: a comparative study》

    这种方法简洁明了,论证翔实,并且可以通过仅仅一行代码来实现:

    Python

    1

    cv2.Laplacian(image,cv2.CV_64F).var()

    只需要将图片中的某一通道(但一般用灰度值)用下面的拉普拉斯掩模做卷积运算:

    1R95HU1-1.jpg

    图2,拉普拉斯掩模

    然后计算方差(即标准差的平方)。

    如果某图片方差低于预先定义的阈值,那么该图片就可以被认为是模糊的。高于阈值,就不是模糊的。

    这种方法凑效的原因就在于拉普拉斯算子定义本身。它被用来测量图片的二阶导数,突出图片中强度快速变化的区域,和 Sobel 以及 Scharr 算子十分相似。并且,和以上算子一样,拉普拉斯算子也经常用于边缘检测。此外,此算法基于以下假设:如果图片具有较高方差,那么它就有较广的频响范围,代表着正常,聚焦准确的图片。但是如果图片具有有较小方差,那么它就有较窄的频响范围,意味着图片中的边缘数量很少。正如我们所知道的,图片越模糊,其边缘就越少。

    很显然,此算法的技巧在于设置合适的阈值。然而,阈值却十分依赖于所应用的领域。阈值太低会导致正常图片被误断为模糊图片,阈值太高会导致模糊图片被误判为正常图片。这种方法在能计算出可接受清晰度评价值的范围的环境中趋于发挥作用,能检测出异常照片。

    检测图片中的模糊量

    到目前为止,本文已经介绍完了计算给定图片模糊度的方法。下面这十二张图片组成的数据集将会在下文用到:

    1R95J358-2.jpg

    图3,图像数据集

    在这些图片中,有些是模糊的,有些是正常的,而要完成目标就是把它们区分开来。

    如前文所述,新建文件并命名为”detect_blur.py”,开始码代码吧:

    Python

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    # import the necessary packages

    fromimutilsimportpaths

    importargparse

    importcv2

    defvariance_of_laplacian(image):

    # compute the Laplacian of the image and then return the focus

    # measure, which is simply the variance of the Laplacian

    returncv2.Laplacian(image,cv2.CV_64F).var()

    # construct the argument parse and parse the arguments

    ap=argparse.ArgumentParser()

    ap.add_argument("-i","--images",required=True,

    help="path to input directory of images")

    ap.add_argument("-t","--threshold",type=float,default=100.0,

    help="focus measures that fall below this value will be considered 'blurry'")

    args=vars(ap.parse_args())

    在代码开始的2-4行,导入了必需的模块。如果读者还没有安装我开发的 imutils 模块,请先安装该模块:

    Python

    1

    $pipintallimutils

    在代码第六行中,定义了 variance_of_laplacian 函数。此函数只接收一个待计算清晰度评价的 image 参数(假设是单通道图像,例如灰度图)。第九行对 image 用3×3拉普拉斯算子做卷积,然后返回方差。

    12-17行处理命令行参数解析。第一个需要的参数是 –image,包含进行模糊度检测的图片数据集路径。

    代码中还定义了一个可选参数 –thresh, 是用于模糊检测的阈值。如果给定图片的清晰度评价值低于该阈值,该图片就会被判定为模糊。如果读者使用其他的数据集,调整该阈值是很重要的。阈值 100 对于本文所使用的数据集效果良好,但是阈值受具体图片内容影响较大,因此为了获得最优结果,读者需要审慎地确定阈值。

    不管你信不信,最艰苦的部分已经完成了。剩下的就只需要写点代码来从磁盘中读入图片,计算拉普拉斯方差然后标记图片为模糊或者正常:

    Python

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    # import the necessary packages

    fromimutilsimportpaths

    importargparse

    importcv2

    defvariance_of_laplacian(image):

    # compute the Laplacian of the image and then return the focus

    # measure, which is simply the variance of the Laplacian

    returncv2.Laplacian(image,cv2.CV_64F).var()

    # construct the argument parse and parse the arguments

    ap=argparse.ArgumentParser()

    ap.add_argument("-i","--images",required=True,

    help="path to input directory of images")

    ap.add_argument("-t","--threshold",type=float,default=100.0,

    help="focus measures that fall below this value will be considered 'blurry'")

    args=vars(ap.parse_args())

    # loop over the input images

    forimagePathinpaths.list_images(args["images"]):

    # load the image, convert it to grayscale, and compute the

    # focus measure of the image using the Variance of Laplacian

    # method

    image=cv2.imread(imagePath)

    gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

    fm=variance_of_laplacian(gray)

    text="Not Blurry"

    # if the focus measure is less than the supplied threshold,

    # then the image should be considered "blurry"

    iffm<args["threshold"]:

    text="Blurry"

    # show the image

    cv2.putText(image,"{}: {:.2f}".format(text,fm),(10,30),

    cv2.FONT_HERSHEY_SIMPLEX,0.8,(0,0,255),3)

    cv2.imshow("Image",image)

    key=cv2.waitKey(0)

    代码第二十行遍历给定目录中的所有图片。对每一幅从磁盘加载的图像,先将它们转化为灰度图,然后用OpenCV执行模糊检测(代码24-27行)。

    如果图像的清晰度低于命令行提供的预置参数,该图像将被标记为“模糊”。

    在代码最后,第35-38行将 text 和计算出的清晰度评价值写入图像中并将图像展示在屏幕上。

    用OpenCV执行模糊检测

    至此,detect_blur.py 脚本已经编写完毕,来练练手吧。打开命令行,敲入以下命令:

    Python

    1

    $pythondetect_blur.py--imagesimages

    1R95H2E-3.jpg

    图4,准确标记为“模糊”

    这张图象的清晰度评价值为 83.17,低于阈值 100,因此标记其为“模糊”。

    1R95K511-4.jpg

    此图像清晰度评价值为64.25,同样标记其为“模糊”。

    1R95I4A-5.jpg

    图6,标记为“正常”

    图像6的清晰度评价值高达 1004.14,比前两张图像高出两个数量级。毫无疑问,此图不模糊,十分清晰。

    1R95I227-6.jpg

    此图唯一模糊的地方在 Jemma 摇动的尾巴上。

    1R95K627-7.jpg

    虽然此图的清晰度评价值低于图7,但是我们还是可以把它准确归入“正常”。

    1R95I4L-8.jpg

    我们可以清除看见上图的模糊。

    1R95GN3-9.jpg

    如此高的清晰度评价值意味着此图“正常”。

    1R95K2U-10.jpg

    此图中包含有大量的模糊。

    1R95H0T-11.jpg

    图12,标记为“模糊”

    1R95HA8-12.jpg

    图13,和图12相比,模糊量大大减少

    1R95M607-13.jpg

    图14,准确标记为“正常”

    1R95GL8-14.jpg

    图15,标记为“模糊”

    总结

    在此文中,我们学习了用 OpenCV 和 Python 来执行模糊检测。

    我们实现了拉普拉斯方差算法,该算法提供给我们一个浮点数来代表具体图像的“模糊度”。该算法快速,简单且易于使用——用拉普拉斯算子与输入图像做卷积然后计算方差即可。如果方差低于预定义阈值,图像就被标记为“模糊”。

    读者必须明白阈值是一个很重要的待调整参数,针对每一个数据集都需要重新设定,阈值太低会导致正常图片被误断为模糊图片,阈值太高会导致模糊图片被误判为正常图片。

    下载代码,然后尝试一下吧!

    展开全文
  • 先读图片拉普拉斯矩阵存储在实验室变量中。
  • OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,网络上一些小伙伴写的一些关于Android版OpenCV的博客,大部分都模糊不清,基本就复制粘贴的,有些甚至没有实践就直接贴上去了,这样...
  • 拉普拉斯图像融合

    千次阅读 2015-06-06 10:43:59
    1.图像金字塔图像金字塔是一个图像集合,集合中所有的图像都来源于同一...拉普拉斯金字塔(Laplacian pyramid):用来从金字塔低层图像中向上采样重建一个图像。2.图像的向上、向下采样下采样下采样使得图像金字塔的层级

    1.图像金字塔

    图像金字塔是一个图像集合,集合中所有的图像都来源于同一个原始图像,而且是通过对原始图像的连续降采样获得,直到达到某个终止条件才停止降采样。
    常见的两种图像金字塔:
    高斯金字塔(Gaussian pyramid): 向下采样图像
    拉普拉斯金字塔(Laplacian pyramid):用来从金字塔低层图像中向上采样重建一个图像。

    2.图像的向上、向下采样

    2.1下采样

    下采样使得图像金字塔的层级越高,图像越小。假设每一层都按从下到上的次序编号,层级(i + 1) 的尺寸表示为Gi+1。则由第i层图像获得第i+1层图像的步骤为:
    1)将Gi与高斯内核卷积:
    这里写图片描述
    2)将所有偶数行和列去除。
    经过上诉处理后,获得的结果图像为原来原图的1/4。不断对迭代上诉步骤就可以得到整个图像金字塔。

    opencv里的实现函数为:
    void cvPyrDown(IplImage *src, IplImage *dst, IplFilter filter = CV_GAUSSIAN_5*5).
    注意最后一个参数仅支持CV_GAUSSIAN_5*5。

    使用示例:
    cvPyrDown( src, result, CV_GAUSSIAN_5x5 ); //高斯变换

    或者Mat格式的:
    pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 )
    函数 pyrDown 接受3个参数:
    tmp: 当前图像, 初始化为原图像 src 。
    dst: 目的图像( 显示图像,为输入图像的一半)
    Size( tmp.cols/2, tmp.rows/2 ) :目的图像大小, 既然我们是向下采样, pyrDown 期待一个一半于输入图像( tmp)的大小。
    注意输入图像的大小(在两个方向)必须是2的冥,否则,将会显示错误。

    2.2上采样

    上采样使得图像变大。步骤:
    1)将图像在每个方向扩大为原来的两倍,新增的行与列以0填充
    2)使用先前同样的内核(乘以4)与放大后的图像卷积,获得新增像素的近似值。

    注意上采样不是下采样的逆操作。因为下采样是一个丢失图像信息的处理过程。

    opencv 实现:
    void cvPyrUp(IplImage * src, IplImage *dst, IplFilter filter = CV_GAUSSIAN_5*5);

    示例:cvPyrUp( src, result, CV_GAUSSIAN_5x5 );

    Mat格式:
    pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 )
    函数 pyrUp 接受了3个参数:
    tmp: 当前图像, 初始化为原图像 src 。
    dst: 目的图像( 显示图像,为输入图像的两倍)
    Size( tmp.cols*2, tmp.rows*2 ) : 目的图像大小, 既然我们是向上采样, pyrUp 期待一个两倍于输入图像( tmp )的大小。

    3.拉普拉斯金字塔

    降采样操作丢失的信息数据形成了拉普拉斯金字塔。拉普拉斯金字塔的第i层定义为:
    这里写图片描述

    借助于opencv,PyrUp()函数实现的功能就是这里写图片描述所定义的,所以,可以使用opencv直接进行拉普拉运算:
    这里写图片描述
    拉普拉斯金字塔与高斯金字塔如下图所示:
    这里写图片描述

    4.图像融合

    利用高斯金字塔与拉普拉斯金字塔,可以将两幅图像进行融合。具体实现步骤为:
    1)每个源图像先被分解成拉普拉斯金字塔(左边列和右边列)
    2)建立高斯金字塔。(二值掩膜)
    3)每个拉普拉斯金字塔图像乘以相应的高斯掩膜(卷积)
    4)进行拼接blendLapPyrs() ; 在每一层上将左右laplacian图像直接拼起来得结果金字塔resultLapPyr。
    5)重建图像: 从最高层结果图
    //将左右laplacian图像拼成的resultLapPyr金字塔中每一层,从上到下插值放大并和下一层相加,即得blend图像结果(reconstructImgFromLapPyramid)

    具体代码:

    #include "opencv2/opencv.hpp"
    using namespace cv;
    
    /************************************************************************/
    /* 说明:
    *金字塔从下到上依次为 [0,1,...,level-1] 层
    *blendMask 为图像的掩模
    *maskGaussianPyramid为金字塔每一层的掩模
    *resultLapPyr 存放每层金字塔中直接用左右两图Laplacian变换拼成的图像
    */
    /************************************************************************/
    
    
    class LaplacianBlending {
    private:
        Mat_<Vec3f> left;
        Mat_<Vec3f> right;
        Mat_<float> blendMask;
    
        vector<Mat_<Vec3f> > leftLapPyr,rightLapPyr,resultLapPyr;//Laplacian Pyramids
        Mat leftHighestLevel, rightHighestLevel, resultHighestLevel;
        vector<Mat_<Vec3f> > maskGaussianPyramid; //masks are 3-channels for easier multiplication with RGB
    
        int levels;
    
        void buildPyramids() {
            buildLaplacianPyramid(left,leftLapPyr,leftHighestLevel);
            buildLaplacianPyramid(right,rightLapPyr,rightHighestLevel);
            buildGaussianPyramid();
        }
    
        void buildGaussianPyramid() {//金字塔内容为每一层的掩模
            assert(leftLapPyr.size()>0);
    
            maskGaussianPyramid.clear();
            Mat currentImg;
            cvtColor(blendMask, currentImg, CV_GRAY2BGR);//store color img of blend mask into maskGaussianPyramid
            maskGaussianPyramid.push_back(currentImg); //0-level
    
            currentImg = blendMask;
            for (int l=1; l<levels+1; l++) {
                Mat _down;
                if (leftLapPyr.size() > l)
                    pyrDown(currentImg, _down, leftLapPyr[l].size());
                else
                    pyrDown(currentImg, _down, leftHighestLevel.size()); //lowest level
    
                Mat down;
                cvtColor(_down, down, CV_GRAY2BGR);
                maskGaussianPyramid.push_back(down);//add color blend mask into mask Pyramid
                currentImg = _down;
            }
        }
    
        void buildLaplacianPyramid(const Mat& img, vector<Mat_<Vec3f> >& lapPyr, Mat& HighestLevel) {
            lapPyr.clear();
            Mat currentImg = img;
            for (int l=0; l<levels; l++) {
                Mat down,up;
                pyrDown(currentImg, down);
                pyrUp(down, up,currentImg.size());
                Mat lap = currentImg - up;
                lapPyr.push_back(lap);
                currentImg = down;
            }
            currentImg.copyTo(HighestLevel);
        }
    
        Mat_<Vec3f> reconstructImgFromLapPyramid() {
            //将左右laplacian图像拼成的resultLapPyr金字塔中每一层
            //从上到下插值放大并相加,即得blend图像结果
            Mat currentImg = resultHighestLevel;
            for (int l=levels-1; l>=0; l--) {
                Mat up;
    
                pyrUp(currentImg, up, resultLapPyr[l].size());
                currentImg = up + resultLapPyr[l];
            }
            return currentImg;
        }
    
    
        //Mat::mul执行两个矩阵按元素相乘或这两个矩阵的除法。该方法返回一个用可选的缩放比率编码了每个元素的数组乘法的临时的对象。
        void blendLapPyrs() {
            //获得每层金字塔中直接用左右两图Laplacian变换拼成的图像resultLapPyr
            resultHighestLevel = leftHighestLevel.mul(maskGaussianPyramid.back()) +
                rightHighestLevel.mul(Scalar(1.0,1.0,1.0) - maskGaussianPyramid.back());
            for (int l=0; l<levels; l++) {
                Mat A = leftLapPyr[l].mul(maskGaussianPyramid[l]);
                Mat antiMask = Scalar(1.0,1.0,1.0) - maskGaussianPyramid[l];
                Mat B = rightLapPyr[l].mul(antiMask);
                Mat_<Vec3f> blendedLevel = A + B;
    
                resultLapPyr.push_back(blendedLevel);
            }
        }
    
    public:
        LaplacianBlending(const Mat_<Vec3f>& _left, const Mat_<Vec3f>& _right, const Mat_<float>& _blendMask, int _levels)://construct function, used in LaplacianBlending lb(l,r,m,4);
          left(_left),right(_right),blendMask(_blendMask),levels(_levels)
          {
              assert(_left.size() == _right.size());
              assert(_left.size() == _blendMask.size());
              buildPyramids();  //construct Laplacian Pyramid and Gaussian Pyramid
              blendLapPyrs();   //blend left & right Pyramids into one Pyramid
          };
    
          Mat_<Vec3f> blend() {
              return reconstructImgFromLapPyramid();//reconstruct Image from Laplacian Pyramid
          }
    };
    
    Mat_<Vec3f> LaplacianBlend(const Mat_<Vec3f>& l, const Mat_<Vec3f>& r, const Mat_<float>& m) {
        LaplacianBlending lb(l,r,m,4);
        return lb.blend();
    }
    
    int main()
    {
        Mat l8u = imread("e:\\testvideo\\left.jpg");
        Mat r8u = imread("e:\\testvideo\\right.jpg");
    
        imshow("left",l8u); 
        imshow("right",r8u);
    
        Mat_<Vec3f> l; l8u.convertTo(l,CV_32F,1.0/255.0);//Vec3f表示有三个通道,即 l[row][column][depth]
        Mat_<Vec3f> r; r8u.convertTo(r,CV_32F,1.0/255.0);
        /*****************    void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;******************/
        /* Performs linear transformation on every source array element:
        dst(x,y,c) = scale*src(x,y,alpha)+beta.
        Arbitrary combination of input and output array depths are allowed
        (number of channels must be the same), thus the function can be used
        for type conversion */
    
        //create blend mask matrix m
        Mat_<float> m(l.rows,l.cols,0.0);                   //将m全部赋值为0
        m(Range::all(),Range(0,m.cols/2)) = 1.0;    //取m全部行&[0,m.cols/2]列,赋值为1.0
    
        Mat_<Vec3f> blend = LaplacianBlend(l, r, m);
        imshow("blended",blend);
    
        waitKey(0);
        return 0;
    }

    result:
    这里写图片描述

    这里写图片描述

    这里写图片描述

    reference:http://blog.csdn.net/abcjennifer/article/details/7628655

    展开全文
  • 我用的是opencv+C++环境来实现的 #include <iostream> #include <opencv2/opencv.hpp> #include <vector>...//手动实现拉普拉斯算子图像 void my_lapulace(const Mat &image...
  • Visual C++数字图像处理典型算法及实现,拉普拉斯锐化算法实现
  • 拉普拉斯图像增强

    2018-04-17 18:49:54
    输入一张图片,运行程序,你将看到增强前,和增强后的效果图。
  • 1.4 基于伽马变换的图像增强 伽马变换主要用于图像的校正,将灰度过高或者灰度过低的图片进行修正,增强对比度。变换公式就是对原图像上每一个像素值做乘积运算: 伽马变换对图像的修正作用其实就是通过增强低灰度...
  • 频域中使用拉普拉斯算子增强图像
  • 对图像首先进行拉普拉斯变换,使得图像的边缘更清晰,之后进行梯度变换,在计算均值与偏度
  • 说明及程序: 1) 检测特征:使用高斯拉普拉斯算子 (LOG) 公式的尺度空间最大化估计的最稳定的哈里斯点。 使用函数“Harris_Laplace_fn.m”进行估算2) 使用 VLFEAT 将 SIFT 描述符与识别的角点相关联。 3)使用SIFT...
  • 内容索引:VC/C++源码,图形处理,拉普拉斯,边缘检测,图像锐化 VC++中使用拉普拉斯边缘检测法对BMP位图进行锐化的实例包。VC++处理图像的时候会用到,锐化功能会使一幅图片的轮廓更清淅,看上去图片也就更清淅,但有...
  • 数值求解平行板电容器的二维拉普拉斯方程使用有限差分方法,使用范数来达到收敛公差=6.00 的标准,迭代次数 N=611。... 右:来自“科学制造商和出口商”的图片和实验室设备”。 http://www.jsexports.com/capacitor
  • 程序简介程序调用Python的opencv模块,根据拉普拉斯变换计算像素方差来作为图片的模糊程度和遮挡程度的指标值,然后根据参考值构建正态分布,根据3西格玛准则,判断图片是否异常,最终实现了模糊检测和遮挡检测功能...
  • VC++中使用拉普拉斯边缘检测法对BMP位图进行锐化的实例包。VC++处理图像的时候会用到,锐化功能会使一幅图片的轮廓更清淅,看上去图片也就更清淅
  • 边缘检测VS2017编译通过,可直接运行 包括 Roberts边缘算子 Sobel边缘检测算子 Prewitt边缘检测算子 Kirsch边缘检测算子 拉普拉斯算子 高斯拉普拉斯算子
  • 用 OpenCV、Python 和拉普拉斯算子来计算图片中的模糊量 一、前言 在做ocr识别的时候,面对一些模糊照片的识别正确率不是很高,所以有必要对被识别照片做模糊判别,而用拉普拉斯方差值可以以浮点数的形势反应图片的...
  • 拉普拉斯变换

    千次阅读 2022-04-25 09:30:28
    拉普拉斯变换 正反变换都要给上收敛域 出发点 jw 容易错 将 jw 换成 s 来自工程师 一、拉普拉斯变换: 1、引入 s为复变量 s=σ+jw s=\sigma+jw s=σ+jw 2、ROC 收敛域 保证傅里叶变换存在 收敛域通常是拉普拉斯...
  • 在CPU上进行传统的拉普拉斯锐化处理非常耗时,特别是对于那些大图片。 在本文中,我们提出了基于Compute Unified Device Architecture(CUDA)(一种图形处理单元(GPU)的计算平台)的Laplacian锐化的并行实现,并...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,447
精华内容 3,378
关键字:

拉普拉斯的图片