机器视觉入门之路(三五,经典canny边缘检测(计算机视觉里程碑))

    技术2022-07-11  93

    图像中的像素插值,我也是在canny中学会的,比如我们旋转后的线图像个个都是插值而成的,你可以看一看前面的博文,诸如此类:

      if (k > -1 && k <= 0)                         {                             float avgGrey = (float)buffer8[(int)j * wh.Width + i];                             float avgGrey1 = (float)buffer8[((int)j + 1) * wh.Width + i];                             grey = avgGrey * (1 - tempf) + avgGrey1 * tempf;                         }                         else                         {                             float avgGrey = (float)buffer8[(int)j * wh.Width + i];                             float avgGrey1 = (float)buffer8[((int)j - 1) * wh.Width + i];                             grey = avgGrey * (1 - tempf) + avgGrey1 * tempf;                         }

    我们的这一节,主要针对非极大值抑制,这是一个很响亮的名字,他里边就使用了很多这种插值,其实所谓插值,浮点像素呗!这就是所谓的亚像素。(需要提高精度,必须如此!)

    上面代码的意思是说:看图

    假定a=buffer(i,j-1);b=buffer(i,j),c=buffer(i,j+1);a,b(avgGrey),c(avgGrey1)为灰度;A,B,C为三个点。

    那么 (k > -1 && k <= 0),直线x=-y就会由B偏向C,假定偏移了0.3=tempf,则,直线x=-y倾斜后与BC相交点的灰度值grey=0.3*c++0.7*b=avgGrey * (1 - tempf) + avgGrey1 * tempf;

    相反,(k>-1),直线就会与AB相交,则同理,仍有 grey = avgGrey * (1 - tempf) + avgGrey1 * tempf;

    以上,虽然是笛卡尔数学坐标系,但在图像坐标系更好理解。

    那么,非极大值抑制也有一段这样的代码:

                                       c=观察中心///                                       /       g3              /                                       /       g4  C   g2              /                                       /               g1                      /                                       /                                     else if (((m_Theta[j, i] >= 135) && (m_Theta[j, i] < 180)) ||                                        ((m_Theta[j, i] >= 315) && (m_Theta[j, i] < 360)))                                    {  //int nPointIdx = i+j*w;                                        g1 = m_M[j + 1, i + 1];                                        g2 = m_M[j, i + 1];                                        g3 = m_M[j - 1, i - 1];                                        g4 = m_M[j, i - 1];                                        dWeight = Math.Abs(m_Q[j, i] / (m_P[j, i] * 1.0));   //タち                                           dTmp1 = g1 * dWeight + g2 * (1 - dWeight);                                        dTmp2 = g3 * dWeight + g4 * (1 - dWeight);                                    }

    对照图,就会很好理解。

    需要说明的是,这条线是穿越点c的梯度方向,重复以下强调过的概念,穿越点c的梯度方向垂直于边缘,当前c的梯度幅值最大,但求出g1g2之间的亚像素点c1的梯度幅值大于c(边缘过c1),或者g3g4之间的亚像素点c2的梯度幅值大于c(边缘过c2),则c点会被舍弃,因为他不在边缘上,而边缘可能在c1上,或在c2上(边缘的定位精度提高了)。

    这就是鼎鼎有名的,非极大值抑制,为什么是这样?因为,我们的像素点是整型的,这里引入了亚像素概念,提高了认知精度,仅此而已。

    以上只是一个片段,因为你至少应该处理四个方向,剩下的只有重复。

    Processed: 0.012, SQL: 12