Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从数学上定义有噪声的轮廓?_Python_Algorithm_Opencv_Math_Image Processing - Fatal编程技术网

Python 如何从数学上定义有噪声的轮廓?

Python 如何从数学上定义有噪声的轮廓?,python,algorithm,opencv,math,image-processing,Python,Algorithm,Opencv,Math,Image Processing,请看下图: 如您所见,某些区域非常嘈杂(边缘非常参差不齐,有很多突然的变化) 我想从图像中消除这些区域,但要做到这一点,我需要能够确定“噪声”的含义 我曾考虑过测量连续轮廓点的角度变化,并用它来确定是否有噪声,但我不相信这是一个稳健的噪声区域检测 有人对如何从数学上定义这些区域有什么建议吗?您可以尝试以下方法: 将图像矩阵分割成一个完全合适的比例 对于每个迭代空间,将白色像素拟合到空间中的线性回归 存储每个部分线性模型的RSME(均方根误差) 计算所有迭代部分的标准偏差 选择描述可容忍“噪声”

请看下图:

如您所见,某些区域非常嘈杂(边缘非常参差不齐,有很多突然的变化)

我想从图像中消除这些区域,但要做到这一点,我需要能够确定“噪声”的含义

我曾考虑过测量连续轮廓点的角度变化,并用它来确定是否有噪声,但我不相信这是一个稳健的噪声区域检测

有人对如何从数学上定义这些区域有什么建议吗?

您可以尝试以下方法:

  • 将图像矩阵分割成一个完全合适的比例

  • 对于每个迭代空间,将白色像素拟合到空间中的线性回归

  • 存储每个部分线性模型的RSME(均方根误差)

  • 计算所有迭代部分的标准偏差

  • 选择描述可容忍“噪声”阈值的标准偏差

  • 您需要尝试不同的“迭代大小”,以找到噪声的最佳描述符


    如果你想比较图片之间的相对噪声水平,最好使用卷积机器学习设计来解决这个问题。

    我试图通过分析它们的曲率值来定义噪声轮廓。 以下是实施细节:

    1. Threshold the gray scale image using fixed threshold value of 250 to retrieve the white edges
    
    2.Extract the contours in the threshold image
    
    3.Calculate the curvature values along each contour
    
    4.From the curvature data we can observer that the noisy contour's curvature values has higher variance value, therefore we can classify such
    noisy contours using certain threshold value.
    
    下面是上述步骤的Python实现。 这里我使用笛卡尔坐标系的曲率估计方程,定义如下

    #函数,用于计算给定轮廓上的曲率值并对噪声轮廓进行分类
    def轮廓曲率(轮廓SPT):
    #基于对称导数的曲率值估计
    #在点(i步),i,(i+步)
    步骤=5
    s1=2*步
    s2=np.功率(s1,2)
    如果len(轮廓SPT)l*0.2:
    返回真值
    其他:
    ct=0
    如果np.abs(曲率2d)<0.0001或np.abs(曲率2d)>5:
    曲率2d=0#局部噪声抑制
    #将曲率值存储在列表中
    附加kp(np.abs(曲率2d))
    #检查曲率值沿轮廓的变化
    var=np.var(kp,ddof=1)
    如果var<0.01:
    打印('差异:',变量)
    返回真值
    返回错误
    def main():
    灰色=cv2.imread('D:/cnt.png',0)
    #使用250作为阈值对图像进行阈值设置
    ret,th1=cv2.阈值(灰色,250255,cv2.阈值_二进制)
    img1,等高线,层次=cv2.findContours(th1,cv2.RETR_树,cv2.CHAIN_近似简单)
    img=cv2.CVT颜色(灰色,cv2.COLOR\U GRAY2RGB)
    #遍历每个轮廓
    对于轮廓中的cnt:
    如果(len(cnt)>50:#忽略小轮廓作为噪声
    标志=轮廓曲率(cnt)
    如果(标志):
    cv2.等高线图(img,[cnt],0,(0,0255),3)
    cv2.imshow(“最终图像”,img)
    cv2.等待键(0)
    如果名称=“\uuuuu main\uuuuuuuu”:
    main()
    
    这是仅显示非噪声(真实)轮廓的输出图像。


    尽管最终输出的图像遗漏了一些真实轮廓,但这里欢迎任何其他改进该算法的想法。

    您可以首先使用Douglas Peucker使用多边形曲线近似每个轮廓(或其一部分),以便最大误差是全局有界的,然后考虑

  • 将近似值的周长与原始曲线的周长进行比较
  • 计算原始曲线上每个点到近似多边形曲线的距离,然后计算该数据集的标准偏差

  • 或者,您可以对同一轮廓进行粗多边形近似和细多边形近似,并计算每粗近似长度的细多边形近似中的分段数。

    我不想用数学方法描述图像,我想用数学方法描述noisi部分。i、 把这样一个区域想象成一个多边形。我怎么知道多边形有噪声?我已经更新了答案。如果你想帮助我理解如何实现这些步骤,请告诉我。我对NN有个人仇视。你不需要使用普通网络来实现这一点,一个简单的线性内核就是你想要的。只是回归。分形维数可能有点过头了。综合曲率?为了使角度变化的测量有意义,在比较部分图像时,它们需要相对于固定大小的范围。我在下面添加了一个建议,建议你如何处理这个问题。最简单的粗略检查可能是检查周长与面积的比率。一个更好的方法是顺时针绕着轮廓走,并将从一个点到下一个点的(绝对)角度相加。高度变化的
    #function to calculate the curvature values along a given contour and classify noisy contour
    def contourCurvature(contourspt):
        #curvature value estimation using symmetric derivation
        # at points (i-step), i, (i+step)
        step = 5
        s1 = 2*step
        s2 = np.power(s1, 2)
        if len(contourspt) < s1:
            return False
    
        kp = []
        l = len(contourspt)
        ct = 0
        for i in range(l):
            p = i - step
            pp = i - s1
            if p < 0:
                p += l
                pp += l
            elif pp < 0:
                pp += l
            n = (i + step) % l
            nn = (i + s1) % l
    
            posPrev = contourspt[p][0]
            posPrevP = contourspt[pp][0]
            posCurr = contourspt[i][0]
            posNext = contourspt[n][0]
            posNextN = contourspt[nn][0]
            #first order derivative at point i w.r.t. x and y
            f1stderX = (posNext[0] - posPrev[0])/s1
            f1stderY = (posNext[1] - posPrev[1])/s1
            # second order derivative at point i w.r.t. x and y
            f2ndderX = (posNextN[0] - 2*posCurr[0] + posPrevP[0])/s2
            f2ndderY = (posNextN[1] - 2*posCurr[1] + posPrevP[1])/s2
    
            if f1stderX != 0 or f1stderY != 0:
                a = f2ndderX*f1stderY - f2ndderY*f1stderX
                b = np.power(np.power(f1stderX,2) + np.power(f1stderY,2), 3/2)
                curvature2D = float("{0:.5f}".format(a/b))
    
                #Check if contour contains any regular section of more than 
                # 20 percent of the contour length
                if np.abs(curvature2D) < 0.005:
                    ct += 1
                    if ct > l*0.2:
                        return True
                else:
                    ct = 0
                if np.abs(curvature2D) < 0.0001 or np.abs(curvature2D) > 5: 
                    curvature2D = 0 #local noise suppression
                #store the curvature values in a list
                kp.append(np.abs(curvature2D))
    
        # check the variance of curvatures values along the contour
        var = np.var(kp, ddof=1)
        if var < 0.01:
            print('Variance: ',var)
            return True
        return False
    
    
    def main():
        gray = cv2.imread('D:/cnt.png', 0)
        #threshold the image using 250 as threhold value
        ret,th1 = cv2.threshold(gray,250,255,cv2.THRESH_BINARY)
        img1,contours,hierarchy = cv2.findContours(th1, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
        img = cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB)
        #iterate through each contour
        for cnt in contours:
            if(len(cnt)>50): #neglect the small contours as noise
                flag = contourCurvature(cnt)
                if(flag):
                    cv2.drawContours(img,[cnt],0,(0,0,255),3)
    
        cv2.imshow('Final image', img)
        cv2.waitKey(0)
    
    if __name__ == "__main__":
        main()