const Mat& CmCurveEx::CalFirDer(int kSize, float linkEndBound, float linkStartBound) { Mat dxMat, dyMat; Sobel(m_img1f, dxMat, CV_32F, 1, 0, kSize); Sobel(m_img1f, dyMat, CV_32F, 0, 1, kSize); for (int y = 0; y < m_h; y++) { float *dx = dxMat.ptr<float>(y); float *dy = dyMat.ptr<float>(y); float *pOrnt = m_pOrnt1f.ptr<float>(y); float *pDer = m_pDer1f.ptr<float>(y); for (int x = 0; x < m_w; x++) { pOrnt[x] = (float)atan2f(dx[x], -dy[x]); if (pOrnt[x] < 0.0f) pOrnt[x] += PI2; pDer[x] = sqrt(dx[x]*dx[x] + dy[x]*dy[x]); } } GaussianBlur(m_pDer1f, m_pDer1f, Size(3, 3), 0); normalize(m_pDer1f, m_pDer1f, 0, 1, NORM_MINMAX); NoneMaximalSuppress(linkEndBound, linkStartBound); return m_pDer1f; }
const Mat& CmCurveEx::CalSecDer(int kSize, float linkEndBound, float linkStartBound) { Mat dxx, dxy, dyy; Sobel(m_img1f, dxx, CV_32F, 2, 0, kSize); Sobel(m_img1f, dxy, CV_32F, 1, 1, kSize); Sobel(m_img1f, dyy, CV_32F, 0, 2, kSize); double eigval[2], eigvec[2][2]; for (int y = 0; y < m_h; y++) { float *xx = dxx.ptr<float>(y); float *xy = dxy.ptr<float>(y); float *yy = dyy.ptr<float>(y); float *pOrnt = m_pOrnt1f.ptr<float>(y); float *pDer = m_pDer1f.ptr<float>(y); for (int x = 0; x < m_w; x++) { compute_eigenvals(yy[x], xy[x], xx[x], eigval, eigvec); pOrnt[x] = (float)atan2(-eigvec[0][1], eigvec[0][0]); //计算法线方向 if (pOrnt[x] < 0.0f) pOrnt[x] += PI2; pDer[x] = float(eigval[0] > 0.0f ? eigval[0] : 0.0f);//计算二阶导数 } } GaussianBlur(m_pDer1f, m_pDer1f, Size(3, 3), 0); normalize(m_pDer1f, m_pDer1f, 0, 1, NORM_MINMAX); NoneMaximalSuppress(linkEndBound, linkStartBound); return m_pDer1f; }
const CmEdges& CmCurveEx::Link(int shortRemoveBound, float lkEnd, float lkStart) { normalize(_pDer1f, _pDer1f, 0, 1, NORM_MINMAX); NoneMaximalSuppress(lkEnd, lkStart); CV_Assert(_pDer1f.data != NULL && _pLabel1i.data != NULL); sort(_StartPnt.begin(), _StartPnt.end(), linePointGreater); _pNext1i = -1; _vEdge.clear(); _vEdge.reserve(int(0.01 * _w * _h)); CEdge crtEdge(0);//当前边 for (vector<PntImp>::iterator it = _StartPnt.begin(); it != _StartPnt.end(); it++) { Point pnt = it->second; if (_pLabel1i.at<int>(pnt) != IND_NMS) continue; findEdge(pnt, crtEdge, FALSE); findEdge(pnt, crtEdge, TRUE); if (crtEdge.pointNum <= shortRemoveBound) { Point point = crtEdge.start; int i, nextInd; for (i = 1; i < crtEdge.pointNum; i++) { _pLabel1i.at<int>(point) = IND_SR; nextInd = _pNext1i.at<int>(point); point += DIRECTION8[nextInd]; } _pLabel1i.at<int>(point) = IND_SR; } else { _vEdge.push_back(crtEdge); crtEdge.index++; } } // Get edge information int edgNum = (int)_vEdge.size(); for (int i = 0; i < edgNum; i++) { CEdge &edge = _vEdge[i]; vector<Point> &pnts = edge.pnts; pnts.resize(edge.pointNum); pnts[0] = edge.start; for (int j = 1; j < edge.pointNum; j++) { pnts[j] = pnts[j-1] + DIRECTION8[_pNext1i.at<int>(pnts[j-1])]; edge.avg += _pDer1f.at<float>(pnts[j]); } edge.avg /= (float)(edge.pointNum); } return _vEdge; }