요즘 open source 에 기여를 해보고 싶어서, 만들어서 pull request 해봐야 겠다고 생각했었다.
github에서 clone해서 시작해보려고 code들을 둘러 보는데 labeling 기능이 추가 되어있었다.
이름은 익숙한 labeling이나 blob은 아니고 connected_compnents 이다.
함수 사용은 아래와 같다.
int cv::connectedComponents | ( | InputArray | image, |
OutputArray | labels, | ||
int | connectivity = 8 , | ||
int | ltype = CV_32S | ||
) |
computes the connected components labeled image of boolean image
image with 4 or 8 way connectivity - returns N, the total number of labels [0, N-1] where 0 represents the background label. ltype specifies the output label image type, an important consideration based on the total number of labels or alternatively the total number of pixels in the source image.
- Parameters
image the image to be labeled labels destination labeled image connectivity 8 or 4 for 8-way or 4-way connectivity respectively ltype output image label type. Currently CV_32S and CV_16U are supported.
blob 하고 나서 object 들의 feature들을 추출해야 할 경우가 대부분인데. 그때는 아래 함수를 사용하면 된다.
int cv::connectedComponentsWithStats | ( | InputArray | image, |
OutputArray | labels, | ||
OutputArray | stats, | ||
OutputArray | centroids, | ||
int | connectivity = 8 , | ||
int | ltype = CV_32S | ||
) |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
- Parameters
image the image to be labeled labels destination labeled image stats statistics output for each label, including the background label, see below for available statistics. Statistics are accessed via stats(label, COLUMN) where COLUMN is one of cv::ConnectedComponentsTypes centroids floating point centroid (x,y) output for each label, including the background label connectivity 8 or 4 for 8-way or 4-way connectivity respectively ltype output image label type. Currently CV_32S and CV_16U are supported.
현재 3.0 에 추가된 connectedComponents algorithm은 아래의 paper 이다.
https://sdm.lbl.gov/~kewu/ps/LBNL-59102.pdf
connectedComponentsWithStats 에는 blob에 대한 아래의 정보들을 추출해 준다.
- //! connected components algorithm output formats
- enum ConnectedComponentsTypes {
- CC_STAT_LEFT = 0, //!< The leftmost (x) coordinate which is the inclusive start of the bounding
- //!< box in the horizontal direction.
- CC_STAT_TOP = 1, //!< The topmost (y) coordinate which is the inclusive start of the bounding
- //!< box in the vertical direction.
- CC_STAT_WIDTH = 2, //!< The horizontal size of the bounding box
- CC_STAT_HEIGHT = 3, //!< The vertical size of the bounding box
- CC_STAT_AREA = 4, //!< The total area (in pixels) of the connected component
- CC_STAT_MAX = 5
- };
아래는 blobImage 로 각 blob의 Gray Sum을 뽑는 함수다.
각 blob의 gray sum을 area 값으로 나누어서 평균 gray값으로 쓸수 있다.
- Mat Stats;
- Mat Center;
- int nNum = connectedComponentsWithStats(m_BinImg,m_LabelImg,Stats,Center);
- double *pContArray = new double [nNum];
- ExtractObjMeanGray(pContArray,nNum);
- delete [] pContArray;
- BOOL CBlobObjectFeature::ExtractObjMeanGray(double *pContArray, int nTotalBlobs)
- {
- BOOL bRet = TRUE;
- int nOriginType = m_OrginContImg.type();
- int nLabelType = m_LabelImg.type();
- ///////////////////////////////이부분 필요 없는데. 그냥 놔둔 이유..//////////////////////
- ///////////////opencv3.1에서는 connectedComponents 함수는 0부터 1++ 된 blob 들만 나온다..////////
- ///////////////하지만 다른 library의 blob알고리즘들은 1++가 아닌것이 더 많았다..///////////////////
- /////////////// 혹 바뀔지도 모르거나 다른 lib들과 호환성을 위해 빼지 않았음////////////////
- map<int, int> mapBlobIdx;
- for(int y=0;y<m_LabelImg.rows;y++)
- {
- for(int x=0;x<m_LabelImg.cols;x++)
- {
- if(m_LabelImg.at<int>(Point(x,y))!=0)
- {
- mapBlobIdx[m_LabelImg.at<int>(Point(x,y))]=0;
- }
- }
- }
- map<int,int>::iterator iter;
- int n=1;
- for(iter = mapBlobIdx.begin();iter!=mapBlobIdx.end();iter++)
- {
- iter->second = n;
- n++;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- ZeroMemory(pContArray,sizeof(double)*nTotalBlobs);
- for(int y=0;y<m_LabelImg.rows;y++)
- {
- for(int x=0;x<m_LabelImg.cols;x++)
- {
- int nLabel;
- double dGray;
- nLabel = m_LabelImg.at<int>(Point(x,y));
- dGray = m_OrginContImg.at<uchar>(Point(x,y));
- pContArray[mapBlobIdx[nLabel]] += dGray;
- }
- }
- return bRet;
- }
댓글 없음:
댓글 쓰기