图像处理矩特征详细介绍_图像处理基础知识 图像矩 - CSDN
  • 图像的几何

    2016-03-31 21:12:34
    是描述图像特征的算子,如今技术已广泛应用于图像检索和识别 、图像匹配 、图像重建 、数字压缩 、数字水印及运动图像序列分析等领域。常见的描述子可以分为以下几种:几何、正交、复数和旋转

            矩是描述图像特征的算子,如今矩技术已广泛应用于图像检索和识别 、图像匹配 、图像重建 、数字压缩 、数字水印及运动图像序列分析等领域。常见的矩描述子可以分为以下几种:几何矩、正交矩、复数矩和旋转矩。

            其中几何矩提出的时间最早且形式简单,对它的研究最为充分。几何矩对简单图像有一定的描述能力,他虽然在区分度上不如其他三种矩,但与其他几种算子比较起来,他极其的简单,一般只需用一个数字就可表达。所以,一般我们是用来做大粒度的区分,用来过滤显然不相关的文档。

    1. 数学中的矩


    2. 图像的几何矩



         补充一点,懂的请无视:

          可能有人会问,为什么像素点的值表示的是概率?meanshift算法里用到的反向投影图就是概率图。什么又是反向投影图呢?举个例子。

        (1)例如灰度图像如下

          Image=

          0 1 2 3

          4 5 6 7

          8 9 10 11

          8 9 14 15

        (2)该灰度图的直方图为(bin指定的区间为[0,4),[4,7),[7,12),[12,16))

          Histogram=

          4 3 7 2

        (3)反向投影图

          Back_Projection=

          4 4 4 4

          3 3 3 7

          7 7 7 7

          7 7 2 2

          可见,反向投影图就是反应了颜色分布的概率图。


    3. 几个图像的不变矩

    HU矩




           这7个不变矩构成一组特征量,Hu.M.K在1962年证明了他们具有旋转,缩放和平移不变性。实际上,在对图片中物体的识别过程中,只有M1和M2不变性保持的比较好,其他的几个不变矩带来的误差比较大,有学者认为只有基于二阶矩的不变矩对二维物体的描述才是真正的具有旋转、缩放和平移不变性(M1和M2刚好都是由二阶矩组成的)。

           由Hu矩组成的特征量对图片进行识别,优点就是速度很快,缺点是识别率比较低。Hu不变矩一般用来识别图像中大的物体,对于物体的形状描述得比较好,图像的纹理特征不能太复杂,像识别水果的形状,或者对于车牌中的简单字符的识别效果会相对好一些。

     

      其他常见的图像矩

            连续正交矩:Zernike矩和Legendre矩

           离散正交矩:Tchebichef矩、Krawtchouk矩、Hahn矩、Racah矩等。

           虽然非正交矩形式简单 、计算快、易于实现,但抗噪性差、基函数非正交 ,且具有较大的信息冗余。连续正交矩的基函数正交,不仅其矩变换可逆 ,且易于图像重建 , 由于其各阶矩相互独立,故具有最小的信息冗余。其不足之处是该矩的基函数只在特定范围内是正交的。

     

    4. OpenCV先关函数

          由OPENCV提供计算中心距、归一化中心距和hu矩的函数为:

    void cvMoments(const CvArr*image,CvMoments*moments,int isBinary=0)

    double cvGetCentralMoment(CvMoments*moments,intx_order,int y_order)

    doublecvGetNormalizedCentralMoment(CvMoments*moments,int x_order,int y_order);

    voidcvGetHuMoments(CvMoments*moments,CvHuMoments*HuMoments);

         其中cvMoments和上面的cvContourMoments是同一个函数。

         同时OPENCV还提供了输入图像直接进行hu矩匹配的函数是

    double cvMatchShapes(constvoid*object1,const void*object2,int method,double parameter=0);

     

    5. 小结

            图像的矩通常描述了该图像形状的全局特征,并被广泛的应用在各种图像处理、计算机视觉和机器人技术领域的目标识别与方位估计中。一阶矩与形状有关,二阶矩显示曲线围绕直线平均值的扩展程度,三阶矩则是关于平均值的对称性的测量。不变矩是图像的统计特性,满足平移、伸缩、旋转均不变的不变性。

            如果把图像看成是一块质量密度不均匀的薄板,其图像的灰度分布函数f(x,y)就是薄板的密度分布函数,则其各阶矩有着不同的含义,如零阶矩表示它的总质量;一阶矩表示它的质心;二阶矩又叫惯性矩,表示图像的大小和方向。事实上,如果仅考虑阶次为2的矩集,则原始图像等同于一个具有确定的大小、方向和离心率,以图像质心为中心且具有恒定辐射率的椭圆。

            由三阶矩以下矩构成的七个矩不变量具有平移、旋转和尺度不变性等等。当密度分布函数发生改变时,图像的实质没有改变,仍然可以看做一个薄板,只是密度分布有所改变。虽然此时各阶矩的值可能发生变化,但由各阶矩计算出的不变矩仍具有平移、旋转和尺度不变性。通过这个思想,可对图像进行简化处理,保留最能反映目标特性的信息,再用简化后的图像计算不变矩特征,可减少计算量。

            研究表明,只有基于二阶矩的不变矩对二维物体的描述才是真正的与旋转、平移和尺度无关的。较高阶的矩对于成像过程中的误差,微小的变形等因素非常敏感,所以相应的不变矩基本上不能用于有效的物体识别。即使是基于二阶矩的不变矩也只能用来识别外形相差特别大的物理,否则他们的不变矩会因为很相似而不能识别。




    展开全文
  • 转载本文请注明详细地址 本文介绍图像矩的含义 本文介绍了不变的计算、应用 本文介绍了如何计算图像相似度

    目录

    • 转载本文请注明详细地址
    • 本文介绍了矩和图像矩的含义
    • 本文介绍了不变矩的计算、应用
    • 本文介绍了如何计算图像相似度

    一、思维导图

    二、普通矩的定义

    1、零阶矩

    2、二阶矩

    3、二阶以上矩

    4、怎么判断是几阶矩

    三、什么是图像矩?

    四、hu不变矩(cv2.humoments())

    1、几何矩

    几何矩前几阶的意义

    2、中心矩(决定了平移不变性)

    3、归一化中心矩(决定了尺度不变性)

    4、hu不变矩计算(决定了旋转不变性)

    5、hu不变矩的性质

    6、hu不变矩的应用与意义

    7、适用条件

    五、Python+opencv实现不变矩计算

    1、自带函数cv2.moments()和cv2.humoments()

    2、自定义函数

    3、结果

    4、 网络上的典型例子

    六、形状相似度计算(cv2.matchshapes())

    参数解析:

    距离计算方法

    自定义距离计算方法


    一、思维导图

    二、普通矩的定义

    1、零阶矩

    2、二阶矩

    3、二阶以上矩

    对于三阶或三阶以上矩,使用图像在轴或轴上的投影比使用图像本身的描述更方便。 
    三阶矩:投影扭曲,描述了图像投影的扭曲程度。扭曲是一个经典统计量,用来衡量关于均值对称分布的偏差程度。 
    四阶矩:投影峰度,峰度是一个用来测量分布峰度的经典统计量。可以计算峰度系数。当峰度系数为0时,表示高斯分布;当峰度系数小于0时,表示平坦的少峰分布;当峰度系数大于0时,表示狭窄的多峰分布。 

    4、怎么判断是几阶矩

    在计算矩的表达式中,将x,y的指数进行相加,得到的值就是图像矩的阶数

    三、什么是图像矩?

    最初接触的矩的概念就是力矩的概念,力与距离的乘积叫做力矩。图像矩因为涉及到两个距离x,y,因此是和两个距离、一个像素强度(灰度值有关),具体定义如下:

    其中:M、N分别是图像的长宽,f是对应像素点的灰度值

     

    四、hu不变矩(cv2.humoments())

    1、几何矩

    几何矩前几阶的意义

    2、中心矩(决定了平移不变性)

    3、归一化中心矩(决定了尺度不变性)

    比较大的争议是在r的求值上,是否加上1,一般情况下加上1会结果准确些

    4、hu不变矩计算(决定了旋转不变性)

    5、hu不变矩的性质

    图像形状平移不变性

    图像形状尺度不变性

    图像形状旋转不变性

    6、hu不变矩的应用与意义

    图像形状匹配

    图像形状区分

    图像形状相似度计算

    7、适用条件

    适用于纹理不复杂的图像

    五、Python+opencv实现不变矩计算

    1、自带函数cv2.moments()和cv2.humoments()

    前者输入的是灰度值图像,后者输入的是由几何矩、中心矩、归一化的中心矩组成的一个字典

    import cv2
    import numpy as np
    np.set_printoptions(suppress=True)#定义输出的精度
    
    
    def sys_moments(img):
        '''
        opencv_python自带求矩以及不变矩的函数
        :param img: 灰度图像,对于二值图像来说就只有两个灰度0和255
        :return: 返回以10为底对数化后的hu不变矩
        '''
        moments = cv2.moments(img)#返回的是一个字典,三阶及以下的几何矩(mpq)、中心矩(mupq)和归一化的矩(nupq)
        humoments = cv2.HuMoments(moments)#根据几何矩(mpq)、中心矩(mupq)和归一化的矩(nupq)计算出hu不变矩
        # 因为直接计算出来的矩可能很小或者很大,因此取对数好比较,这里的对数底数为e,通过对数除法的性质将其转换为以10为底的对数
        humoment = (np.log(np.abs(humoments)))/np.log(10)
        return humoment

    2、自定义函数

    def def_moments(img_gray):
        '''
        自定义求矩函数,主要是根据公式将一个个参数求出
        :param img_gray:  灰度图像,对于二值图像来说就只有两个灰度0和255
        :return: 返回以10为底对数化后的hu不变矩
        '''
        '''
            由于7个不变矩的变化范围很大,为了便于比较,可利用取对数的方法进行数据压缩;
            同时考虑到不变矩有可能出现负值的情况,因此,在取对数之前先取绝对值
            经修正后的不变矩特征具有平移 、旋转和比例不变性
        '''
        # 标准矩定义为m_pq = sumsum(x^p * y^q * f(x, y))其中f(x,y)为像素点处的灰度值
        row, col = img_gray.shape
        # 计算图像的0阶几何矩
        m00 = img_gray.sum()
        ##初始化一到三阶几何矩
        #计算一阶矩阵
        m10 = m01 = 0
        # 计算图像的二阶、三阶几何矩
        m11 = m20 = m02 = m12 = m21 = m30 = m03 = 0
        for i in range(row):
            m10 += (i * img_gray[i]).sum()#sum表示将一行的灰度值进行相加
            m20 += (i ** 2 * img_gray[i]).sum()
            m30 += (i ** 3 * img_gray[i]).sum()
            for j in range(col):
                m11 += i * j * img_gray[i][j]
                m12 += i * j ** 2 * img_gray[i][j]
                m21 += i ** 2 * j * img_gray[i][j]
        for j in range(col):
            m01 += (j * img_gray[:, j]).sum()
            m02 += (j ** 2 * img_gray[:, j]).sum()
            m30 += (j ** 3 * img_gray[:, j]).sum()
        # 由标准矩我们可以得到图像的"重心"
        u10 = m10 / m00
        u01 = m01 / m00
        # 计算图像的二阶中心矩、三阶中心矩
        y00 = m00
        y10 = y01 = 0
        y11 = m11 - u01 * m10
        y20 = m20 - u10 * m10
        y02 = m02 - u01 * m01
        y30 = m30 - 3 * u10 * m20 + 2 * u10 ** 2 * m10
        y12 = m12 - 2 * u01 * m11 - u10 * m02 + 2 * u01 ** 2 * m10
        y21 = m21 - 2 * u10 * m11 - u01 * m20 + 2 * u10 ** 2 * m01
        y03 = m03 - 3 * u01 * m02 + 2 * u01 ** 2 * m01
        # 计算图像的归一化中心矩
        n20 = y20 / m00 ** 2
        n02 = y02 / m00 ** 2
        n11 = y11 / m00 ** 2
        n30 = y30 / m00 ** 2.5
        n03 = y03 / m00 ** 2.5
        n12 = y12 / m00 ** 2.5
        n21 = y21 / m00 ** 2.5
        # 计算图像的七个不变矩
        h1 = n20 + n02
        h2 = (n20 - n02) ** 2 + 4 * n11 ** 2
        h3 = (n30 - 3 * n12) ** 2 + (3 * n21 - n03) ** 2
        h4 = (n30 + n12) ** 2 + (n21 + n03) ** 2
        h5 = (n30 - 3 * n12) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n21 - n03) * (n21 + n03) \
                                                                                         * (3 * (n30 + n12) ** 2 - (
            n21 + n03) ** 2)
        h6 = (n20 - n02) * ((n30 + n12) ** 2 - (n21 + n03) ** 2) + 4 * n11 * (n30 + n12) * (n21 + n03)
        h7 = (3 * n21 - n03) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n12 - n30) * (n21 + n03) \
                                                                                         * (3 * (n30 + n12) ** 2 - (
            n21 + n03) ** 2)
        inv_m7 = [h1, h2, h3, h4, h5, h6, h7]
        humoments = np.log(np.abs(inv_m7))
        return humoments
    
    
    def main():
        img = cv2.imread('roi.png',0)
        sys_humoments = sys_moments(img)
        def_humoments = def_moments(img)
        print('自带函数:\n',sys_humoments)
        print('自定义函数:\n',def_humoments)
    
    if __name__ == '__main__':
        main()

    3、结果

    结果不是很理想,可能在编写计算中心矩和不变矩的公式的时候出现了错误,可以自行纠正

     

    4、 网络上的典型例子

    可以看到,图像K0.png就是字母K,而S0.png就是字母S。接下来,我们将字母S移到S1中。在s2。png中移动+缩放。我们添加了一些旋转使S3.png,并进一步翻转图像使S4.png。

    注意,S0、S1、S2、S3和S4的所有Hu矩的值都很接近,除了S4的最后Hu矩的符号被翻转了。另外,注意它们都与K0非常不同。

    六、形状相似度计算(cv2.matchshapes())

    我们将学习如何使用Hu矩来找出两个图形之间的距离。如果距离小,形状的外观接近,如果距离大,形状的外观较远。

    OpenCV提供了一个名为matchShapes的实用程序函数,它可以获取两幅图像(或轮廓),并使用Hu矩查找它们之间的距离。所以,你不需要明确地计算Hu力矩。简单地对图像进行二值化并使用matchShapes。

    dist = matchShapes(contour1, contour2, method, parameter)

    这里是利用两个图像的不变矩来进行距离的计算

    参数解析:

    前两个参数是两个图像

    method:进行距离计算的方法即公式,分别有以下三种方法

    parameter:一般设置为0即可

    距离计算方法

    注意:以下的计算方法的hu不变矩阵都是经过log函数变换的

    两个图像(im1和im2)是相似的,如果上面的距离很小。你可以使用任何距离测量。它们通常产生相似的结果。我个人更喜欢d2。

    自定义距离计算方法

    七、参考文献

    https://zhuanlan.zhihu.com/p/117344473(中文版)

    https://www.learnopencv.com/shape-matching-using-hu-moments-c-python/(英文版)

    hu不变矩的原理:https://www.researchgate.net/publication/224146066_Analysis_of_Hu's_moment_invariants_on_image_scaling_and_rotation

    https://blog.csdn.net/qq_37207090/article/details/83986950

    https://blog.csdn.net/qq_23541329/article/details/60963456

    展开全文
  • 转载请注明详细地址 本文简单介绍图像常见几何特征的概念以及求解方法 本文介绍了Python和opencv求解几何特征的常用方法
    • 转载请注明详细地址
    • 本文简单介绍了图像常见几何特征的概念以及求解方法
    • 本文介绍了Python和opencv求解几何特征的常用方法

    目录

    其他形状外接轮廓的方法可以参考:《OpenCV-Python——第17.3章:轮廓形状拟合(边界矩形,最小外接圆...)及性质》

    一、获得轮廓

    二、面积

    1、cv2.connectedComponentsWithStats()

    stats参数解析

    2、cv2.contourArea()函数

    三、周长

    1、cv2.arcLength(contours[0],True)

    四、细长度

    1、绘制外接矩形(cv2.rectangle()函数)

    2、得到矩形的角点坐标和长宽cv2.boundingRect()函数

    3、求解最小外接矩形(cv2.minAreaRect()函数)

    4、绘制最小外接矩形:cv2.boxPoints()函数和cv2.polylines()函数

    step1 角点坐标获得cv2.boxPoints()

    step2 将角点坐标全部转换为整数

    step3 依次连接起来cv2.polylines()

    5、细长度的计算

    五、区间占空比

    六、重心

    七、图像上添加文字cv2.putText()函数

    八、完整代码


    一、获得轮廓

    在进行轮廓几何特征的提取之前,首先要做的就是得到轮廓,得到轮廓常用的函数有:
    cv2.findcontours()

    contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy[, offset]]] )
     
        参数1:源图像
        参数2:轮廓的检索方式,这篇文章主要讲解这个参数
        参数3:一般用 cv.CHAIN_APPROX_SIMPLE,就表示用尽可能少的像素点表示轮廓
        contours:图像轮廓坐标,是一个列表
        hierarchy:[Next, Previous, First Child, Parent],文中有详细解释

    具体可见:《【图像处理】——Python+opencv实现二值图像的轮廓边界跟踪以及轮廓面积周长的求解(findcontours函数和contourArea函数)》

    二、面积

    一般指的是轮廓内所包含的所有像素的个数,但是为了方便计算加快计算的速度,一般会采样一种近似地方法去估算面积,常用的有将轮廓近似成一个多边形,然后进行求解,在Python—opencv中,有两种方式可以对轮廓面积进行求解

    1、cv2.connectedComponentsWithStats()

    具体看见:《【图像处理】——实现二值图像的轮廓边界跟踪以及轮廓面积周长的求解(connectedComponentsWithStats()函数和connectedComponents()函数)

     retval, labels, stats, centroids = 
    connectedComponentsWithStats(image, labels=None, stats=None, centroids=None, connectivity=None, ltype=None)

     这个函数返回值stats中的最后一个元素就是轮廓区域的面积,通过提取可以得到

    stats参数解析

    stats参数是一个numpy数组,每一行代表一个轮廓,每一行固定为5个参数,依次是:

        CC_STAT_LEFT 组件的左上角点像素点坐标的X位置

        CC_STAT_TOP 组件的左上角点像素点坐标的Y位置

        CC_STAT_WIDTH 组件外接矩形的宽度,计算方式为用每一个轮廓中最右边的点的x坐标减去最左边的点的x坐标

        CC_STAT_HEIGHT 组件外接矩形的高度,计算方式为用每一个轮廓中最下边的点的y坐标减去最上边的点的y坐标

        CC_STAT_AREA 当前连通组件的面积(像素单位),这里统计的是轮廓所包含的像素点的个数,不是外接矩形的面积

    所以stats的shape为:mx5,m是轮廓的个数,第一个轮廓是背景轮廓,前两个参数为0,0


    2、cv2.contourArea()函数

    这个函数可以针对每一个轮廓求得近似的面积,返回的是一个常数

    contours,layer_num = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    #面积1
    area1 = cv2.contourArea(contours[0])
    #面积2
    _,labels,stats,centroids = cv2.connectedComponentsWithStats(binary)
    area2 = stats[1][4]

    三、周长

    周长指的是轮廓的像素点总数,也常用各个像素点的中点连线的多边形长度进行度量,若是对角线方向则为根号2个像素格,否则为1个像素格长度

    常用的函数为:

    length = cv2.arcLength(contours[0],True)

    1、cv2.arcLength(contours[0],True)

    arcLength(contour, closed)

    参数解析:

    contour:轮廓点集

    closed:表明轮廓是否封闭与否,TRUE则表示封闭,FALSE则表示非封闭

    #周长
    length = cv2.arcLength(contours[0],True)

    四、细长度

    细长度表征图像中待识别区域的紧凑性,它的计算是由待识别区域的最小外接矩形得到,该最小外接矩形长轴和短轴的比值即为区域的细长度,表达式如下:

    1、绘制外接矩形(cv2.rectangle()函数)

    这个函数的原理就是取轮廓点集最上面的点、最下面的点、最左边的点和最右边的点作为外接矩形的四个点的坐标,这个矩形不一定是最小外接矩形,其边与坐标轴平行或者垂直

    img = rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
    
    img:进行绘制矩形的图像
    
    pt1:矩形左上角角点坐标,是一个元组
    
    pt2:矩形右下角角点坐标,是一个元组
    
    color:绘制矩形的颜色,一般通过RGB的表示方式(R.G,B)
    
    thickness:绘制矩形的线宽,如果是负数,则将轮廓区域进行填充
    
    linetype:线型
    
    rect = cv2.rectangle(rgb1,(stats[1][0],stats[1][1]),(stats[1][0]+stats[1][2],stats[1][1]+stats[1][3]),(0,0,255),2)

    2、得到矩形的角点坐标和长宽cv2.boundingRect()函数

    #得到外接矩形的左上角点坐标和长宽
    x,y,h,w = cv2.boundingRect(contours[0])

    3、求解最小外接矩形(cv2.minAreaRect()函数)

    实际上求解最小外接矩形的方法就是将图像沿逆时针或者顺时针按照一定的度数进行旋转,每旋转一次,求解一次轮廓的外接矩形的面积,记录每次旋转的度数、左上角点坐标、矩形长宽,根据三角函数可以得到旋转后的角点坐标,等旋转完成一周后,取面积最小的即为最小外接矩形

    img = minAreaRect(points)

    points:就是轮廓的点集

    返回的是:img = ((x,y),(h,w),α)

    #返回的是一个元组,第一个元素是左上角点坐标组成的元组,第二个元素是矩形宽高组成的元组,第三个是旋转的角度
    min_rect = cv2.minAreaRect(contours[0])

    4、绘制最小外接矩形:cv2.boxPoints()函数和cv2.polylines()函数

    要想在原图像中绘制出最小外接矩形,则需要知道矩形的四个角点坐标,这四个角点坐标实际上就是在旋转的时候记录后进行根据记录的角度和三角函数进行转换过来的,知道后通过绘制多边形的方法将点依次连接即可

    step1 角点坐标获得cv2.boxPoints()

    box = cv2.boxPoints(min_rect)#返回的是一个numpy矩阵
    min_rect:是一个元组
    
    

    返回的是由角点组成的numpy矩阵

    step2 将角点坐标全部转换为整数

    box = np.int0(box)#将其转换为整数,否则会报错

    step3 依次连接起来cv2.polylines()

    img = polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)

    参数解析:

    img:绘制矩形的图像

    pts:装有矩形角点的点阵(一般是由boxpoints()函数得到)

    isClosed:指定绘制的矩形是否为封闭的,TRUE表示封闭

    color:绘制矩形的线条的颜色,用元组表示

    thickness:线宽

    linetype:线型

    返回参数:返回的是绘制后的图像

    min_rect_img = cv2.polylines(rgb2,[box],True,(0,255,0),2)

    5、细长度的计算

    直接利用得到的数据即可获得

    #最小外接矩形
    min_rect = cv2.minAreaRect(contours[0])#返回的是一个元组,第一个元素是左上角点坐标组成的元组,第二个元素是矩形宽高组成的元组,第三个是旋转的角度
    #细长度
    min_rect_h = min_rect[1][0]
    min_rect_w = min_rect[1][1]
    e = min_rect_h/min_rect_w

    五、区间占空比

    区间占空比指的是将轮廓区域的面积除以外接矩形的面积,这里的外接矩形一般指的是最小外接矩形

    #区域占空比(轮廓区域面积除以最小外接矩形面积)
    ee = area1/min_rect_area

    六、重心

    重心描述的是待识别区域的全局特性,反映的是区域内部像素点的分布。如果待识别区域是均匀的,密度设为1则区域的重心同时也是是区域的几何中心,它可通过计算所有像素点的平均值得到

    七、图像上添加文字cv2.putText()函数

    cv2.putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)

    img:需要添加文字的图像

    text:添加的文字内容,一定是字符串

    org:相当于一个文本框的左上角点坐标

    fontface:文字大小

    fontscale:文字比例

    color:文字颜色,以元组的形式表达

    thickness:线宽

    linetype:线型

    text2 = "width:" + str(int(min_rect[1][1]))
    cv2.putText(rgb1,text1, (10, 30), 3, 0.5, (0, 255, 0), 1, cv2.LINE_AA, 0)

    八、完整代码

    import cv2
    import numpy as np
    
    rgb1 = cv2.imread('roi.png')
    rgb2 = cv2.imread('roi.png')
    rgb3 = cv2.imread('roi.png')
    
    img = cv2.imread('roi.png',0)
    ret,binary = cv2.threshold(img,100,255,cv2.THRESH_BINARY)
    contours,layer_num = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    #面积1
    area1 = cv2.contourArea(contours[0])
    #面积2
    _,labels,stats,centroids = cv2.connectedComponentsWithStats(binary)
    area2 = stats[1][4]
    
    #周长
    length = cv2.arcLength(contours[0],True)
    
    #得到外接矩形的左上角点坐标和长宽
    x,y,w,h = cv2.boundingRect(contours[0])
    
    #外接矩形
    rect = cv2.rectangle(rgb1,(stats[1][0],stats[1][1]),(stats[1][0]+stats[1][2],stats[1][1]+stats[1][3]),(0,0,255),2)
    rect_area = w*h
    
    #最小外接矩形
    min_rect = cv2.minAreaRect(contours[0])#返回的是一个元组,第一个元素是左上角点坐标组成的元组,第二个元素是矩形宽高组成的元组,第三个是旋转的角度
    # print(min_rect)((530.0443725585938, 113.73445892333984), (40.497230529785156, 137.21890258789062), -86.68222045898438)
    
    #获得最小外接矩形的四个角点坐标
    box = cv2.boxPoints(min_rect)#返回的是一个numpy矩阵
    min_rect_area = cv2.contourArea(box)
    
    #绘制最小外接矩形,通过多边形绘制的方法进行绘制
    box = np.int0(box)#将其转换为整数,否则会报错
    min_rect_img = cv2.polylines(rgb2,[box],True,(0,255,0),2)
    
    #细长度
    min_rect_h = min_rect[1][0]
    min_rect_w = min_rect[1][1]
    e = min_rect_h/min_rect_w
    
    #区域占空比(轮廓区域面积除以最小外接矩形面积)
    ee = area1/min_rect_area
    
    #质心
    centroid = centroids[0]
    
    text1 = 'height:'+ str(int(min_rect[1][0]))
    text2 = "width:" + str(int(min_rect[1][1]))
    cv2.putText(rgb1,text1, (10, 30), 3, 0.5, (0, 255, 0), 1, cv2.LINE_AA, 0)
    cv2.putText(rgb1,text2, (10, 60), 3, 0.5, (0, 255, 0), 1, cv2.LINE_AA, 0)
    cv2.imshow('rect',rect)
    cv2.imshow('min_rect',min_rect_img)
    cv2.imshow('rgb',rgb3)
    cv2.waitKey(0)
    
    print(area1)
    print(area2)
    print(rect_area)
    print(min_rect_area)
    print(e)
    print(ee)
    print(centroid)

    展开全文
  • 图像处理中的数学原理归类 ...我的“图像处理中的数学原理”...该书详细介绍图像处理中的数学原理,为你打开一道通往图像世界的数学之门。以下是最新版本的该书的完整目录,方便各位网友查阅以及确定本书是否符合你的...

    图像处理中的数学原理归类
    原文:https://blog.csdn.net/baimafujinji/article/details/48467225

    我的“图像处理中的数学原理”专栏中之系列文章已经以《图像处理中的数学修炼》为名结集出版(清华大学出版社)。该书详细介绍图像处理中的数学原理,为你打开一道通往图像世界的数学之门。以下是最新版本的该书的完整目录,方便各位网友查阅以及确定本书是否符合你的选购目标:

    第1章 必不可少的数学基础

    1.1 极限及其应用
    1.1.1 数列的极限
    1.1.2 级数的敛散
    1.1.3 函数的极限
    1.1.4 极限的应用

    1.2 微分中值定理
    1.2.1 罗尔中值定理
    1.2.2 拉格朗日中值定理
    1.2.3 柯西中值定理
    1.2.4 泰勒公式
    1.2.5 海塞矩阵与多元函数极值

    1.3 向量代数与场论
    1.3.1 牛顿-莱布尼茨公式
    1.3.2 内积与外积
    1.3.3 方向导数与梯度
    1.3.4 曲线积分
    1.3.5 格林公式
    1.3.6 积分与路径无关条件
    1.3.7 曲面积分
    1.3.8 高斯公式与散度
    1.3.9 斯托克斯公式与旋度
    本章参考文献

    第2章 更进一步的数学内容

    2.1 傅立叶级数展开
    2.1.1 函数项级数的概念
    2.1.2 函数项级数的性质
    2.1.3 傅立叶级数的概念
    2.1.4 傅立叶变换的由来
    2.1.5 卷积定理及其证明

    2.2 复变函数论初步
    2.2.1 解析函数
    2.2.2 复变积分
    2.2.3 基本定理
    2.2.4 级数展开

    2.3 凸函数与詹森不等式

    2.3.1 凸函数的概念

    2.3.2 詹森不等式及其证明

    2.3.3 詹森不等式的应用

    2.4 常用经典数值解法

    2.4.1 牛顿迭代法

    2.4.2 雅各比迭代

    2.4.3 高斯迭代法

    2.4.4 托马斯算法

    本章参考文献

    第3章 泛函分析以及变分法

    3.1 勒贝格积分理论
    3.1.1 点集的勒贝格测度
    3.1.2 可测函数及其性质
    3.1.3 勒贝格积分的定义
    3.1.4 积分序列极限定理
    3.2 泛函与抽象空间
    3.2.1 线性空间
    3.2.2 距离空间
    3.2.3 赋范空间
    3.2.4 巴拿赫空间
    3.2.5 内积空间
    3.2.6 希尔伯特空间
    3.2.7 索伯列夫空间
    3.3 从泛函到变分法
    3.3.1 理解泛函的概念
    3.3.2 关于的变分概念
    3.3.3 变分法的基本方程
    3.3.4 理解哈密尔顿原理
    3.3.5 等式约束下的变分
    3.3.6 巴拿赫不动点定理
    3.3.7 有界变差函数空间

    本章参考文献

    第4章 概率论与统计学基础

    4.1 概率论的基本概念

    4.2 随机变量数字特征

    4.2.1  期望
    
    4.2.2  方差
    
    4.2.3  矩与矩母函数
    
    4.2.4  协方差与协方差矩阵
    

    4.3 基本概率分布模型

    4.3.1  离散概率分布
    
    4.3.2  连续概率分布
    

    4.4 概率论中的重要定理

    4.4.1  大数定理
    
    4.4.2  中央极限定理
    

    4.5 随机采样

    4.5.1  随机采样分布
    
    4.5.2  蒙特卡洛采样
    

    4.6 参数估计

    4.7 假设检验

    4.7.1  基本概念
    
    4.7.2  两类错误
    
    4.7.3  均值检验
    

    4.8 极大似然估计

    4.8.1  极大似然法的基本原理
    
    4.8.2  求极大似然估计的方法
    

    4.9 贝叶斯推断

    4.9.1  先验概率与后验概率
    
    4.9.2  共轭分布
    

    参考文献

    第5章 子带编码与小波变换

    5.1 图像编码的理论基础
    5.1.1 率失真函数
    5.1.2 香农下边界
    5.1.3 无记忆高斯信源
    5.1.4 有记忆高斯信源
    5.2 子带编码基本原理
    5.2.1 数字信号处理基础
    5.2.2 多抽样率信号处理
    5.2.3 图像信息子带分解
    5.3 哈尔函数及其变换
    5.3.1 哈尔函数的定义
    5.3.2 哈尔函数的性质
    5.3.3 酉矩阵与酉变换
    5.3.4 二维离散线性变换
    5.3.5 哈尔基函数
    5.3.6 哈尔变换
    5.4 小波及其数学原理
    5.4.1 小波的历史
    5.4.2 理解小波的概念
    5.4.3 多分辨率分析
    5.4.4 小波函数的构建
    5.4.5 小波序列展开
    5.4.6 离散小波变换
    5.4.7 连续小波变换
    5.4.8 小波的容许条件与基本特征
    5.5 快速小波变换算法
    5.5.1 快速小波正变换
    5.5.2 快速小波逆变换
    5.5.3 图像的小波变换

    5.6 小波在图像处理中的应用

    本章参考文献

    第6章 正交变换与图像压缩
    6.1 傅立叶变换
    6.1.1 信号处理中的傅立叶变换

        1. 连续时间,连续频率——傅立叶变换
    
        2. 连续时间,离散频率——傅立叶级数
    
        3. 离散时间,连续频率——序列的傅立叶变换
    
        4. 离散时间,离散频率——离散的傅立叶变换
    
    6.1.2  数字图像的傅立叶变换
    6.1.3  快速傅立叶变换的算法
    

    6.2 离散余弦变换
    6.2.1 基本概念及数学描述
    6.2.2 离散余弦变换的快速算法
    6.2.3 离散余弦变换的意义与应用
    6.3 沃尔什-阿达马变换
    6.3.1 沃尔什函数
    6.3.2 离散沃尔什变换及其快速算法
    6.3.3 沃尔什变换的应用
    6.4 卡洛南-洛伊变换
    6.4.1 一些必备的基础概念
    6.4.2 主成分变换的推导
    6.4.3 主成分变换的实现
    6.4.4 基于K-L变换的图像压缩
    本章参考文献

    第7章 无所不在的高斯分布
    7.1 卷积积分与邻域处理
    7.1.1 卷积积分的概念
    7.1.2 模板与邻域处理
    7.1.3 图像的高斯平滑
    7.2 边缘检测与微分算子
    7.2.1 哈密尔顿算子
    7.2.2 拉普拉斯算子
    7.2.3 高斯-拉普拉斯算子
    7.2.4 高斯差分算子
    7.3 保持边缘的平滑处理
    7.3.1 双边滤波算法应用
    7.3.2 各向异性扩散滤波
    7.3.3 基于全变差的方法
    7.4 数学物理方程的应用
    7.4.1 泊松方程的推导
    7.4.2 图像的泊松编辑
    7.4.3 离散化数值求解

    7.4.4  基于稀疏矩阵的解法
    

    7.5 多尺度空间及其构建
    7.5.1 高斯滤波与多尺度空间的构建
    7.5.2 基于各向异性扩散的尺度空间
    本章参考文献

    第8章 处理彩色图像

    8.1 从认识色彩开始

    8.1.1  什么是颜色
    
    8.1.2  颜色的属性
    
        1. 色相
    
        2. 亮度
    
        3. 纯度
    
    8.1.3  光源能量分布图
    

    8.2 CIE色度图

    8.2.1  CIE色彩模型的建立
    
    8.2.2  CIE色度图的理解
    
        1. 确定互补颜色
    
        2. 确定色光主波
    
        3. 定义颜色区域
    
    8.2.3  CIE色度图的后续发展
    

    8.3 常用的色彩空间

    8.3.1  RGB颜色空间
    
    8.3.2 CMY/CMYK颜色空间
    
    8.3.3  HSV/HSB颜色空间
    
    8.3.4  HSI/HSL颜色空间
    
    8.3.5  Lab颜色空间
    
    8.3.6 YUV/YCbCr颜色空间
    

    8.4 色彩空间的转换方法

    8.4.1  RGB转换到HSV的方法
    
    8.4.2  RGB转换到HSI的方法
    
    8.4.3  RGB转换到YUV的方法
    
    8.4.4  RGB转换到YCbCr的方法
    

    8.5 基于直方图的色彩增强

    8.5.1     普通直方图均衡
    
    8.5.2    CLAHE算法
    
    8.5.3     直方图规定化
    

    8.6 暗通道先验的去雾算法

    8.6.1  暗通道的概念与意义
    
    8.6.2  暗通道去雾霾的原理
    
    8.6.3  算法实现与应用
    

    本章参考文献

    作者:白马负金羁
    来源:CSDN
    原文:https://blog.csdn.net/baimafujinji/article/details/48467225
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • SIFT(Scale-invariant feature transform)是一种检测局部特征的... 的描述子得到特征并进行图像特征点匹配,获得了良好效果,详细解析如下: 算法描述 SIFT特征不只具有尺度不变性,即使改变旋转角度,图像

    转载来源:http://blog.csdn.net/abcjennifer/article/details/7639681

    我毛华望QQ849886241,个人博客http://blog.csdn.net/my_share

     

     

    SIFT(Scale-invariant feature transform)是一种检测局部特征的算法,该算法通过求一幅图中的特征点(interest points,or corner points)及其有关scale 和 orientation 的描述子得到特征并进行图像特征点匹配,获得了良好效果,详细解析如下:

    算法描述

    SIFT特征不只具有尺度不变性,即使改变旋转角度,图像亮度或拍摄视角,仍然能够得到好的检测效果。整个算法分为以下几个部分:

    1. 构建尺度空间

    这是一个初始化操作,尺度空间理论目的是模拟图像数据的多尺度特征

    高斯卷积核是实现尺度变换的唯一线性核,于是一副二维图像的尺度空间定义为:


    其中 G(x,y,σ) 是尺度可变高斯函数 

    (x,y)是空间坐标,是尺度坐标。σ大小决定图像的平滑程度,大尺度对应图像的概貌特征,小尺度对应图像的细节特征。大的σ值对应粗糙尺度(低分辨率),反之,对应精细尺度(高分辨率)。为了有效的在尺度空间检测到稳定的关键点,提出了高斯差分尺度空间(DOG scale-space)。利用不同尺度的高斯差分核与图像卷积生成。

    下图所示不同σ下图像尺度空间:



    关于尺度空间的理解说明:2kσ中的2是必须的,尺度空间是连续的。在  Lowe的论文中 ,将第0层的初始尺度定为1.6(最模糊),图片的初始尺度定为0.5(最清晰). 在检测极值点前对原始图像的高斯平滑以致图像丢失高频信息,所以 Lowe 建议在建立尺度空间前首先对原始图像长宽扩展一倍,以保留原始图像信息,增加特征点数量。尺度越大图像越模糊。 


    图像金字塔的建立:对于一幅图像I,建立其在不同尺度(scale)的图像,也成为子八度(octave),这是为了scale-invariant,也就是在任何尺度都能够有对应的特征点,第一个子八度的scale为原图大小,后面每个octave为上一个octave降采样的结果,即原图的1/4(长宽分别减半),构成下一个子八度(高一层金字塔)。



    尺度空间的所有取值,i为octave的塔数(第几个塔),s为每塔层数

    由图片size决定建几个塔,每塔几层图像(S一般为3-5)0塔的第0层是原始图像(或你double后的图像),往上每一层是对其下一层进行Laplacian变换(高斯卷积,其中σ值渐大,例如可以是σ, k*σ, k*k*σ),直观上看来越往上图片越模糊。塔间的图片是降采样关系,例如1塔的第0层可以由0塔的第3down sample得到,然后进行与0塔类似的高斯卷积操作。


    2. LoG近似DoG找到关键点<检测DOG尺度空间极值点>

    为了寻找尺度空间的极值点,每一个采样点要和它所有的相邻点比较,看其是否比它的图像域和尺度域的相邻点大或者小。如图所示,中间的检测点和它同尺度的8个相邻点和上下相邻尺度对应的9×2个点共26个点比较,以确保在尺度空间和二维图像空间都检测到极值点。 一个点如果在DOG尺度空间本层以及上下两层的26个领域中是最大或最小值时,就认为该点是图像在该尺度下的一个特征点,如图所示。


    同一组中的相邻尺度(由于k的取值关系,肯定是上下层)之间进行寻找


    s=3的情况

     在极值比较的过程中,每一组图像的首末两层是无法进行极值比较的,为了满足尺度变化的连续性(下面有详解)
    我们在每一组图像的顶层继续用高斯模糊生成了 3 幅图像,高斯金字塔有每组S+3层图像。DOG金字塔每组有S+2层图像.

    ==========================================
    这里有的童鞋不理解什么叫“为了满足尺度变化的连续性”,现在做仔细阐述:
    假设s=3,也就是每个塔里有3层,则k=21/s=21/3,那么按照上图可得Gauss Space和DoG space 分别有3个(s个)和2个(s-1个)分量,在DoG space中,1st-octave两项分别是σ,kσ; 2nd-octave两项分别是2σ,2kσ;由于无法比较极值,我们必须在高斯空间继续添加高斯模糊项,使得形成σ,kσ,k2σ,k3σ,k4σ这样就可以选择DoG space中的中间三项kσ,k2σ,k3σ(只有左右都有才能有极值),那么下一octave中(由上一层降采样获得)所得三项即为2kσ,2k2σ,2k3σ,其首项2kσ=24/3。刚好与上一octave末项k3σ=23/3尺度变化连续起来,所以每次要在Gaussian space添加3项,每组(塔)共S+3层图像,相应的DoG金字塔有S+2层图像。
    ==========================================

    使用Laplacian of Gaussian能够很好地找到找到图像中的兴趣点,但是需要大量的计算量,所以使用Difference of Gaussian图像的极大极小值近似寻找特征点.DOG算子计算简单,是尺度归一化的LoG算子的近似,有关DOG寻找特征点的介绍及方法详见http://blog.csdn.net/abcjennifer/article/details/7639488极值点检测用的Non-Maximal Suppression


    3. 除去不好的特征点

    这一步本质上要去掉DoG局部曲率非常不对称的像素。


    通过拟和三维二次函数以精确确定关键点的位置和尺度(达到亚像素精度),同时去除低对比度的关键点和不稳定的边缘响应点(因为DoG算子会产生较强的边缘响应),以增强匹配稳定性、提高抗噪声能力,在这里使用近似Harris Corner检测器。

    ①空间尺度函数泰勒展开式如下:对上式求导,并令其为0,得到精确的位置, 得

    ②在已经检测到的特征点中,要去掉低对比度的特征点和不稳定的边缘响应点。去除低对比度的点:把公式(2)代入公式(1),即在DoG Space的极值点处D(x)取值,只取前两项可得:


    若   ,该特征点就保留下来,否则丢弃。

    ③边缘响应的去除
    一个定义不好的高斯差分算子的极值在横跨边缘的地方有较大的主曲率,而在垂直边缘的方向有较小的主曲率。主曲率通过一个2×2 的Hessian矩阵H求出:

    导数由采样点相邻差估计得到。

    D的主曲率和H的特征值成正比,令α为较大特征值,β为较小的特征值,则

    令α=γβ,则

     (r + 1)2/r的值在两个特征值相等的时候最小,随着r的增大而增大,因此,为了检测主曲率是否在某域值r下,只需检测

    if (α+β)/ αβ> (r+1)2/r, throw it out.   在Lowe的文章中,取r=10。



    4. 给特征点赋值一个128维方向参数

    上一步中确定了每幅图中的特征点,为每个特征点计算一个方向,依照这个方向做进一步的计算, 利用关键点邻域像素的梯度方向分布特性为每个关键点指定方向参数,使算子具备旋转不变性。


    为(x,y)处梯度的模值和方向公式。其中L所用的尺度为每个关键点各自所在的尺度。至此,图像的关键点已经检测完毕,每个关键点有三个信息:位置,所处尺度、方向,由此可以确定一个SIFT特征区域。


    梯度直方图的范围是0~360度,其中每10度一个柱,总共36个柱。随着距
          中心点越远的领域其对直方图的贡献也响应减小.Lowe论文中还提到要使用高斯函数对直方图进行平滑,减少突变的影响。

    在实际计算时,我们在以关键点为中心的邻域窗口内采样,并用直方图统计邻域像素的梯度方向。梯度直方图的范围是0~360度,其中每45度一个柱,总共8个柱, 或者每10度一个柱,总共36个柱。Lowe论文中还提到要使用高斯函数对直方图进行平滑,减少突变的影响。直方图的峰值则代表了该关键点处邻域梯度的主方向,即作为该关键点的方向


    直方图中的峰值就是主方向,其他的达到最大值80%的方向可作为辅助方向

    由梯度方向直方图确定主梯度方向

    该步中将建立所有scale中特征点的描述子(128维)

    Identify peak and assign orientation and sum of magnitude to key point.
      The user may choose a threshold to exclude key points based on their assigned sum of magnitudes.


    关键点描述子的生成步骤


     通过对关键点周围图像区域分块,计算块内梯度直方图,生成具有独特性的向量,这个向量是该区域图像信息的一种抽象,具有唯一性。


    5. 关键点描述子的生成

    首先将坐标轴旋转为关键点的方向,以确保旋转不变性。以关键点为中心取8×8的窗口。

    Figure.16*16的图中其中1/4的特征点梯度方向及scale,右图为其加权到8个主方向后的效果。

    图左部分的中央为当前关键点的位置,每个小格代表关键点邻域所在尺度空间的一个像素,利用公式求得每个像素的梯度幅值与梯度方向,箭头方向代表该像素的梯度方向,箭头长度代表梯度模值,然后用高斯窗口对其进行加权运算。


    图中蓝色的圈代表高斯加权的范围(越靠近关键点的像素梯度方向信息贡献越大)。然后在每4×4的小块上计算8个方向的梯度方向直方图,绘制每个梯度方向的累加值,即可形成一个种子点,如图右部分示。此图中一个关键点由2×2共4个种子点组成,每个种子点有8个方向向量信息。这种邻域方向性信息联合的思想增强了算法抗噪声的能力,同时对于含有定位误差的特征匹配也提供了较好的容错性。


    计算keypoint周围的16*16的window中每一个像素的梯度,而且使用高斯下降函数降低远离中心的权重。

    在每个4*4的1/16象限中,通过加权梯度值加到直方图8个方向区间中的一个,计算出一个梯度方向直方图。

    这样就可以对每个feature形成一个4*4*8=128维的描述子,每一维都可以表示4*4个格子中一个的scale/orientation. 将这个向量归一化之后,就进一步去除了光照的影响。

    5. 根据SIFT进行Match

    生成了A、B两幅图的描述子,(分别是k1*128维和k2*128维),就将两图中各个scale(所有scale)的描述子进行匹配,匹配上128维即可表示两个特征点match上了。


    实际计算过程中,为了增强匹配的稳健性,Lowe建议对每个关键点使用4×4共16个种子点来描述,这样对于一个关键点就可以产生128个数据,即最终形成128维的SIFT特征向量。此时SIFT特征向量已经去除了尺度变化、旋转等几何变形因素的影响,再继续将特征向量的长度归一化,则可以进一步去除光照变化的影响。 当两幅图像的SIFT特征向量生成后,下一步我们采用关键点特征向量的欧式距离来作为两幅图像中关键点的相似性判定度量。取图像1中的某个关键点,并找出其与图像2中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离少于某个比例阈值,则接受这一对匹配点。降低这个比例阈值,SIFT匹配点数目会减少,但更加稳定。为了排除因为图像遮挡和背景混乱而产生的无匹配关系的关键点,Lowe提出了比较最近邻距离与次近邻距离的方法,距离比率ratio小于某个阈值的认为是正确匹配。因为对于错误匹配,由于特征空间的高维性,相似的距离可能有大量其他的错误匹配,从而它的ratio值比较高。Lowe推荐ratio的阈值为0.8。但作者对大量任意存在尺度、旋转和亮度变化的两幅图片进行匹配,结果表明ratio取值在0. 4~0. 6之间最佳,小于0. 4的很少有匹配点,大于0. 6的则存在大量错误匹配点。(如果这个地方你要改进,最好给出一个匹配率和ration之间的关系图,这样才有说服力)作者建议ratio的取值原则如下:

    ratio=0. 4 对于准确度要求高的匹配;
    ratio=0. 6 对于匹配点数目要求比较多的匹配; 
    ratio=0. 5 一般情况下。
    也可按如下原则:当最近邻距离<200时ratio=0. 6,反之ratio=0. 4。ratio的取值策略能排分错误匹配点。



    当两幅图像的SIFT特征向量生成后,下一步我们采用关键点特征向量的欧式距离来作为两幅图像中关键点的相似性判定度量。取图像1中的某个关键点,并找出其与图像2中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离少于某个比例阈值,则接受这一对匹配点。降低这个比例阈值,SIFT匹配点数目会减少,但更加稳定。

     

    实验结果:







    Python+opencv实现:


    1. import cv2  
    2. import numpy as np  
    3. #import pdb   
    4. #pdb.set_trace()#turn on the pdb prompt   
    5.   
    6. #read image   
    7. img = cv2.imread('D:\privacy\picture\little girl.jpg',cv2.IMREAD_COLOR)  
    8. gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  
    9. cv2.imshow('origin',img);  
    10.   
    11. #SIFT   
    12. detector = cv2.SIFT()  
    13. keypoints = detector.detect(gray,None)  
    14. img = cv2.drawKeypoints(gray,keypoints)  
    15. #img = cv2.drawKeypoints(gray,keypoints,flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)   
    16. cv2.imshow('test',img);  
    17. cv2.waitKey(0)  
    18. cv2.destroyAllWindows()  
    import cv2
    import numpy as np
    #import pdb
    #pdb.set_trace()#turn on the pdb prompt
    
    #read image
    img = cv2.imread('D:\privacy\picture\little girl.jpg',cv2.IMREAD_COLOR)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    cv2.imshow('origin',img);
    
    #SIFT
    detector = cv2.SIFT()
    keypoints = detector.detect(gray,None)
    img = cv2.drawKeypoints(gray,keypoints)
    #img = cv2.drawKeypoints(gray,keypoints,flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
    cv2.imshow('test',img);
    cv2.waitKey(0)
    cv2.destroyAllWindows()



    C实现:


    1. // FeatureDetector.cpp : Defines the entry point for the console application.   
    2. //     
    3. //  Created by Rachel on 14-1-12.     
    4. //  Copyright (c) 2013年 ZJU. All rights reserved.     
    5. //     
    6.   
    7. #include "stdafx.h"   
    8. #include "highgui.h"   
    9. #include "cv.h"   
    10. #include "vector"   
    11. #include "opencv\cxcore.hpp"   
    12. #include "iostream"   
    13. #include "opencv.hpp"   
    14. #include "nonfree.hpp"   
    15. #include "showhelper.h"   
    16.   
    17. using namespace cv;  
    18. using namespace std;  
    19.   
    20. int _tmain(int argc, _TCHAR* argv[])  
    21. {  
    22.     //Load Image    
    23.     Mat c_src1 =  imread( "..\\Images\\3.jpg");  
    24.     Mat c_src2 = imread("..\\Images\\4.jpg");  
    25.     Mat src1 = imread( "..\\Images\\3.jpg", CV_LOAD_IMAGE_GRAYSCALE);  
    26.     Mat src2 = imread( "..\\Images\\4.jpg", CV_LOAD_IMAGE_GRAYSCALE);  
    27.     if( !src1.data || !src2.data )  
    28.     { std::cout<< " --(!) Error reading images " << std::endl; return -1; }  
    29.   
    30.     //sift feature detect   
    31.     SiftFeatureDetector detector;  
    32.     std::vector<KeyPoint> kp1, kp2;  
    33.   
    34.     detector.detect( src1, kp1 );  
    35.     detector.detect( src2, kp2 );  
    36.     SiftDescriptorExtractor extractor;  
    37.     Mat des1,des2;//descriptor   
    38.     extractor.compute(src1,kp1,des1);  
    39.     extractor.compute(src2,kp2,des2);     
    40.     Mat res1,res2;   
    41.     int drawmode = DrawMatchesFlags::DRAW_RICH_KEYPOINTS;  
    42.     drawKeypoints(c_src1,kp1,res1,Scalar::all(-1),drawmode);//在内存中画出特征点   
    43.     drawKeypoints(c_src2,kp2,res2,Scalar::all(-1),drawmode);  
    44.     cout<<"size of description of Img1: "<<kp1.size()<<endl;  
    45.     cout<<"size of description of Img2: "<<kp2.size()<<endl;  
    46.   
    47.     //write the size of features on picture   
    48.     CvFont font;      
    49.     double hScale=1;     
    50.     double vScale=1;      
    51.     int lineWidth=2;// 相当于写字的线条       
    52.     cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);//初始化字体,准备写到图片上的      
    53.     // cvPoint 为起笔的x,y坐标      
    54.     IplImage* transimg1 = cvCloneImage(&(IplImage) res1);  
    55.     IplImage* transimg2 = cvCloneImage(&(IplImage) res2);  
    56.           
    57.     char str1[20],str2[20];  
    58.     sprintf(str1,"%d",kp1.size());  
    59.     sprintf(str2,"%d",kp2.size());  
    60.   
    61.   
    62.     const char* str = str1;  
    63.     cvPutText(transimg1,str1,cvPoint(280,230),&font,CV_RGB(255,0,0));//在图片中输出字符    
    64.   
    65.     str = str2;  
    66.     cvPutText(transimg2,str2,cvPoint(280,230),&font,CV_RGB(255,0,0));//在图片中输出字符    
    67.   
    68.     //imshow("Description 1",res1);   
    69.     cvShowImage("descriptor1",transimg1);  
    70.     cvShowImage("descriptor2",transimg2);  
    71.   
    72.     BFMatcher matcher(NORM_L2);  
    73.     vector<DMatch> matches;  
    74.     matcher.match(des1,des2,matches);  
    75.     Mat img_match;  
    76.     drawMatches(src1,kp1,src2,kp2,matches,img_match);//,Scalar::all(-1),Scalar::all(-1),vector<char>(),drawmode);   
    77.     cout<<"number of matched points: "<<matches.size()<<endl;  
    78.     imshow("matches",img_match);  
    79.     cvWaitKey();  
    80.     cvDestroyAllWindows();  
    81.   
    82.     return 0;  
    83. }  
    // FeatureDetector.cpp : Defines the entry point for the console application.
    //  
    //  Created by Rachel on 14-1-12.  
    //  Copyright (c) 2013年 ZJU. All rights reserved.  
    //  
    
    #include "stdafx.h"
    #include "highgui.h"
    #include "cv.h"
    #include "vector"
    #include "opencv\cxcore.hpp"
    #include "iostream"
    #include "opencv.hpp"
    #include "nonfree.hpp"
    #include "showhelper.h"
    
    using namespace cv;
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	//Load Image 
    	Mat c_src1 =  imread( "..\\Images\\3.jpg");
    	Mat c_src2 = imread("..\\Images\\4.jpg");
    	Mat src1 = imread( "..\\Images\\3.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    	Mat src2 = imread( "..\\Images\\4.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    	if( !src1.data || !src2.data )
    	{ std::cout<< " --(!) Error reading images " << std::endl; return -1; }
    
    	//sift feature detect
    	SiftFeatureDetector detector;
    	std::vector<KeyPoint> kp1, kp2;
    
    	detector.detect( src1, kp1 );
    	detector.detect( src2, kp2 );
    	SiftDescriptorExtractor extractor;
    	Mat des1,des2;//descriptor
    	extractor.compute(src1,kp1,des1);
    	extractor.compute(src2,kp2,des2);	
    	Mat res1,res2; 
    	int drawmode = DrawMatchesFlags::DRAW_RICH_KEYPOINTS;
    	drawKeypoints(c_src1,kp1,res1,Scalar::all(-1),drawmode);//在内存中画出特征点
    	drawKeypoints(c_src2,kp2,res2,Scalar::all(-1),drawmode);
    	cout<<"size of description of Img1: "<<kp1.size()<<endl;
    	cout<<"size of description of Img2: "<<kp2.size()<<endl;
    
    	//write the size of features on picture
    	CvFont font;    
    	double hScale=1;   
    	double vScale=1;    
    	int lineWidth=2;// 相当于写字的线条    
    	cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);//初始化字体,准备写到图片上的   
    	// cvPoint 为起笔的x,y坐标   
    	IplImage* transimg1 = cvCloneImage(&(IplImage) res1);
    	IplImage* transimg2 = cvCloneImage(&(IplImage) res2);
    		
    	char str1[20],str2[20];
    	sprintf(str1,"%d",kp1.size());
    	sprintf(str2,"%d",kp2.size());
    
    
    	const char* str = str1;
    	cvPutText(transimg1,str1,cvPoint(280,230),&font,CV_RGB(255,0,0));//在图片中输出字符 
    
    	str = str2;
    	cvPutText(transimg2,str2,cvPoint(280,230),&font,CV_RGB(255,0,0));//在图片中输出字符 
    
    	//imshow("Description 1",res1);
    	cvShowImage("descriptor1",transimg1);
    	cvShowImage("descriptor2",transimg2);
    
    	BFMatcher matcher(NORM_L2);
    	vector<DMatch> matches;
    	matcher.match(des1,des2,matches);
    	Mat img_match;
    	drawMatches(src1,kp1,src2,kp2,matches,img_match);//,Scalar::all(-1),Scalar::all(-1),vector<char>(),drawmode);
    	cout<<"number of matched points: "<<matches.size()<<endl;
    	imshow("matches",img_match);
    	cvWaitKey();
    	cvDestroyAllWindows();
    
    	return 0;
    }
    





    ===============================
    基本概念及一些补充
    什么是局部特征?
      •局部特征从总体上说是图像或在视觉领域中一些有别于其周围的地方
      •局部特征通常是描述一块区域,使其能具有高可区分度
      •局部特征的好坏直接会决定着后面分类、识别是否会得到一个好的结果
     局部特征需具备的特性
      •重复性
      •可区分性
      •准确性
      •数量以及效率
      •不变性
     局部特征提取算法-sift
      •SIFT算法由D.G.Lowe 1999年提出,2004年完善总结。后来Y.Ke将其描述子部分用PCA代替直方图的方式,对其进行改进。
       •SIFT算法是一种提取局部特征的算法,在尺度空间寻找极值点,提取位置,尺度,旋转不变量
      •SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性。
      •独特性好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配。
      •多量性,即使少数的几个物体也可以产生大量SIFT特征向量。
      •可扩展性,可以很方便的与其他形式的特征向量进行联合。
    尺度空间理论
      •尺度空间理论目的是模拟图像数据的多尺度特征
      •其基本思想是在视觉信息图像信息处理模型中引入一个被视为尺度的参数, 通过连续变化尺度参数获得不同尺度下的视觉处理信息, 然后综合这些信息以深入地挖掘图像的本质特征。
    描述子生成的细节
      •以极值点为中心点,并且以此点所处于的高斯尺度sigma值作为半径因子。对于远离中心点的梯度值降低对其所处区域的直方图的贡献,防止一些突变的影响。
      •每个极值点对其进行三线性插值,这样可以把此极值点的贡献均衡的分到直方图中相邻的柱子上
    归一化处理
      •在求出4*4*8的128维特征向量后,此时SIFT特征向量已经去除了尺度变化、旋转等几何变形因素的影响。而图像的对比度变化相当于每个像素点乘上一个因子,光照变化是每个像素点加上一个值,但这些对图像归一化的梯度没有影响。因此将特征向量的长度归一化,则可以进一步去除光照变化的影响。
      •对于一些非线性的光照变化,SIFT并不具备不变性,但由于这类变化影响的主要是梯度的幅值变化,对梯度的方向影响较小,因此作者通过限制梯度幅值的值来减少这类变化造成的影响。
    PCA-SIFT算法
      •PCA-SIFT与标准SIFT有相同的亚像素位置,尺度和主方向。但在第4步计算描述子的设计,采用的主成分分析的技术。
      •下面介绍一下其特征描述子计算的部分:
        •用特征点周围的41×41的像斑计算它的主元,并用PCA-SIFT将原来的2×39×39维的向量降成20维,以达到更精确的表示方式。
        •它的主要步骤为,对每一个关键点:在关键点周围提取一个41×41的像斑于给定的尺度,旋转到它的主方向 ;计算39×39水平和垂直的梯度,形成一个大小为3042的矢量;用预先计算好的投影矩阵n×3042与此矢量相乘;这样生成一个大小为n的PCA-SIFT描述子。
    ===============================

    辅助资料:





    ===============================


    Reference:

    Lowe SIFT 原文:http://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf

    SIFT 的C实现:https://github.com/robwhess/opensift/blob/master/src

    MATLAB 应用Sift算子的模式识别方法:http://blog.csdn.net/abcjennifer/article/details/7372880

    http://blog.csdn.net/abcjennifer/article/details/7365882

    http://en.wikipedia.org/wiki/Scale-invariant_feature_transform#David_Lowe.27s_method

    http://blog.sciencenet.cn/blog-613779-475881.html

    http://www.cnblogs.com/linyunzju/archive/2011/06/14/2080950.html

    http://www.cnblogs.com/linyunzju/archive/2011/06/14/2080951.html

    http://blog.csdn.net/ijuliet/article/details/4640624

    http://www.cnblogs.com/cfantaisie/archive/2011/06/14/2080917.html  (部分图片有误,以本文中的图片为准)

    展开全文
  • 数字图像处理学习笔记(一):特征检测和匹配综述 参考博客: 特征点的匹配 1、特征点概述 如何高效且准确的匹配出两个不同视角的图像中的同一个物体,是许多计算机视觉应用中的第一步。虽然图像在计算机中是以...
  • 图像处理时,受外界光线的干扰一般比较大,假如在阈值分割时采用固 定阈值,那么在环境改变时分割效果受影响极大,那么为了避免此影响就 必须采用动态阈值,自动求出合适的阈值进行分割。 本文的介绍几...
  • 数字图像处理技术的开发对数学基础的要求很高,一些不断涌现的新方法中,眼花缭乱的数学推导令很多期望深入研究的人望而却步。一个正规理工科学生大致已经具备了包括微积分、线性代数、概率论在内的数学基础。但在...
  • 图像处理系统中特征提取的详细介绍 摘要:  特征图像处理领域起着非常重要的作用。在提取特征之前,对图像进行各种预处理,例如二值化、阈值、调整大小、归一化等。然后,特征提取技术来获得图像特征,这在...
  • 本书也是一本介绍图像技术的教材,但它有不同的视点和方式。至少有两点值得指出: 首先,作者完全采用了一种问答的形式来组织和介绍相关内容。全书从头到尾共设计了472个问题(很多是由学生提出来的),有问有答,...
  • 图像识别无非是 特征提取 加分类识别从本节开始, 我们将逐步从数字图像处理向图像识别过渡。 严格地说, 图像特征提取属于图像分析的范畴, 是数字图像处理的高级阶段, 同时也是图像识别的开始。本文主要包括以下...
  • 本书以 OpenCV 开源库为基础实现图像处理领域的很多通用算法,并结合当今图像处理领域前沿技术, 对多个典型工程实例进行讲解及实现。全书内容覆盖面广,由基础到进阶,各个技术点均提供详细的代码
  • 最简单的你可以把整幅图像的像素矩阵作为图像特征进行训练和判断分类,但毕竟该特征太过简单并不是都适用,所以下面介绍一下各种分类器训练所需要特征的提取算法,如LBP、不变、小波。 1、LBP特征提取算法 答:...
  • 图像几何轮廓特征 ...为什么介么说,因为在本人实际的项目当中,很多时候处理算法都是基于图像的几何轮廓特征进行计算的,例如角点计算的几种算法HOG、SIFT、SUFT…都是基于图像的几何轮廓特征的基本理论上。
  • Cv图像处理

    2018-05-05 13:53:57
    注意:本章描述图像处理和分析的一些函数。大多数函数都是针对两维象素数组的,这里,我们称这些数组为“图像”,但是它们不一定非得是IplImage 结构,也可以是CvMat或者CvMatND结构。目录 [隐藏]1 梯度、边缘和角...
  • 图像处理 结构分析 运动分析与对象跟踪 模式识别 相机标定和三维重建  1、图像处理 图像处理主要针对二维像素数组,但是我们称这些数组为“图像”,但是它们不一定非得是IplImage 结构,也可以是CvMat或者...
  • 图像处理URL

    2016-04-26 14:07:05
    随笔分类 - 图像处理/图像增强等 图像增强; 图像复原; 图像重建; 图像分割; 图像特效; 图像匹配; 图像形态学处理; 图像几何处理; 图像正交变换; 人工智能; 跟踪; 图像处理之增强---图像模糊检测 ...
  • 图像局部特征提取

    2019-10-02 20:33:42
    图像特征可以包括颜色特征、纹理特征、形状特征以及局部特征点等。其中局部特点具有很好的稳定性,不容易受外界环境的干扰。图像特征提取是图像分析与图像识别的前提,它是将高维的图像数据进行简化表达最有效的方式...
  • 图像处理小结

    2018-10-11 09:00:19
    1、 彩色图像、灰度图像、二值图像和索引图像区别? 答:(1)彩色图像,每个像素通常是由红(R)、绿(G)、蓝(B)三个分量来表示的,分量介于(0,255)。M、N分别表示图像的行列数,三个M x N的二维矩阵分别...
  • 图像处理与计算机视觉算法及应用(第2版) 基本信息:   书名原文:Algorithms for Image Processing and Computer Vision,Second Edition ISBN978-7-302-28222-8 定价:49元 作译者:(加拿大) 帕科尔...
1 2 3 4 5 ... 20
收藏数 865
精华内容 346
关键字:

图像处理矩特征详细介绍