OpenCV 를 사용 하여 그림 연결 도 메 인 수 를 가 져 오고 서로 다른 색상 으로 메 시 지 를 표시 합 니 다.
코드
//######################### #########################
cv::Scalar icvprGetRandomColor()
{
uchar r = 255 * (rand() / (1.0 + RAND_MAX));
uchar g = 255 * (rand() / (1.0 + RAND_MAX));
uchar b = 255 * (rand() / (1.0 + RAND_MAX));
return cv::Scalar(b, g, r);
}
//######################### #########################
//######################## )#########################
void ConnectedCountBySeedFill(const cv::Mat& _binImg, cv::Mat& _lableImg, int &iConnectedAreaCount)
{
// 1 : , , 0 ,
//========== 1 ============================================
int top, bottom; //【 】
int leftImage, rightImage;
int borderType = BORDER_CONSTANT; //BORDER_REPLICATE
//【 】
top = (int)(1); bottom = (int)(1);
leftImage = (int)(1); rightImage = (int)(1);
Mat _binImg2, _binImg3;
_binImg.copyTo(_binImg2);
// value
Scalar value(0); //
//
copyMakeBorder(_binImg2, _binImg3, top, bottom, leftImage, rightImage, borderType, value);
//========== 1 ============================================
// connected component analysis (4-component)
// use seed filling algorithm
// 1. begin with a foreground pixel and push its foreground neighbors into a stack;
// 2. pop the top pixel on the stack and label it with the same label until the stack is empty
//
// foreground pixel: _binImg(x,y) = 1
// background pixel: _binImg(x,y) = 0
if (_binImg3.empty() ||
_binImg3.type() != CV_8UC1)
{
return;
}
_lableImg.release();
_binImg3.convertTo(_lableImg, CV_32SC1);
int icount = 0;
int label = 1; // start by 2
int rows = _binImg3.rows - 1;
int cols = _binImg3.cols - 1;
for (int i = 1; i < rows - 1; i++)
{
int* data = _lableImg.ptr<int>(i); //
for (int j = 1; j < cols - 1; j++)
{
if (data[j] == 1) // 0
{
std::stack<std::pair<int, int>> neighborPixels; //
neighborPixels.push(std::pair<int, int>(i, j)); // : <i,j> , ,
++label; // ,
while (!neighborPixels.empty())
{
//
std::pair<int, int> curPixel = neighborPixels.top();
int curX = curPixel.first;
int curY = curPixel.second;
_lableImg.at<int>(curX, curY) = label; //
// ( )
neighborPixels.pop();
// 8
if (_lableImg.at<int>(curX, curY - 1) == 1)
{//
neighborPixels.push(std::pair<int, int>(curX, curY - 1)); //
}
if (_lableImg.at<int>(curX, curY + 1) == 1)
{//
neighborPixels.push(std::pair<int, int>(curX, curY + 1)); //
}
if (_lableImg.at<int>(curX - 1, curY) == 1)
{//
neighborPixels.push(std::pair<int, int>(curX - 1, curY)); //
}
if (_lableImg.at<int>(curX + 1, curY) == 1)
{//
neighborPixels.push(std::pair<int, int>(curX + 1, curY)); //
}
//=============== 8 ======================================================
if (_lableImg.at<int>(curX - 1, curY - 1) == 1)
{//
neighborPixels.push(std::pair<int, int>(curX - 1, curY - 1)); //
}
if (_lableImg.at<int>(curX - 1, curY + 1) == 1)
{//
neighborPixels.push(std::pair<int, int>(curX - 1, curY + 1)); //
}
if (_lableImg.at<int>(curX + 1, curY - 1) == 1)
{//
neighborPixels.push(std::pair<int, int>(curX + 1, curY - 1)); //
}
if (_lableImg.at<int>(curX + 1, curY + 1) == 1)
{//
neighborPixels.push(std::pair<int, int>(curX + 1, curY + 1)); //
}
//=============== 8 ======================================================
}
}
}
}
iConnectedAreaCount = label - 1; // label 2
int a = 0;
}
###########################################################
//############# #####################################
Mat PaintColor(Mat src, int iConnectedAreaCount)
{
int rows = src.rows;
int cols = src.cols;
//cv::Scalar(b, g, r);
std::map<int, cv::Scalar> colors;
for (int n = 1; n <= iConnectedAreaCount + 1; n++)
{
colors[n] = icvprGetRandomColor(); //
cv::Scalar color = colors[n];
int a = color[0];
int b = color[1];
int c = color[2];
int d = 0;
}
Mat dst2(rows, cols, CV_8UC3);
dst2 = cv::Scalar::all(0);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
int value = src.at<int>(i, j);
if (value>1)
{
cv::Scalar color = colors[value];
int a = color[0];
int b = color[1];
int c = color[2];
dst2.at<Vec3b>(i, j)[0] = color[0];
dst2.at<Vec3b>(i, j)[1] = color[1];
dst2.at<Vec3b>(i, j)[2] = color[2];
}
}
}
return dst2;
}
//############# ##################################
//######## ##########################################
Mat binImage = cv::imread("D:\\sxl\\ \\testImages\\22.jpg", 0);
threshold(binImage, binImage, 50, 1, CV_THRESH_BINARY_INV);
//
Mat labelImg;
int iConnectedAreaCount = 0; //
ConnectedCountBySeedFill(binImage, labelImg, iConnectedAreaCount);//
int a=iConnectedAreaCount;
//
Mat dstColor2=PaintColor(labelImg,iConnectedAreaCount);
imshow("colorImg", dstColor2);
Mat grayImg;
labelImg *= 10;
labelImg.convertTo(grayImg, CV_8UC1);
imshow("labelImg", grayImg);
waitKey(0);
//######## ##########################################
추가 지식:Opencv 빠 른 연결 도 메 인 획득ndarray 데이터 의 연결 도 메 인 찾기 에 있어 opencv 는 인 터 페 이 스 를 제공 하여 매우 편리 합 니 다.
import cv2
import numpy as np
img = np.array([
[0, 255, 255, 0, 0, 0, 255, 255,],
[0, 0, 255, 0, 255, 255, 255, 0],
[0, 0, 0, 0, 255, 255, 0, 255],
[255, 255, 0, 0, 0, 0, 0, 0],
[255, 255, 0, 0, 0, 0, 0, 0],
[255, 255, 0, 0, 0, 0, 0, 0]
], dtype=np.uint8)
num, labels = cv2.connectedComponents(img)
labels_dict = {i:[] for i in range(1, num+1)}
height, width = img.shape
for h in range(height):
for w in range(width):
if labels[h][w] in labels_dict:
labels_dict[labels[h][w]].append([h,w])
cv2.connected Components()함수 가 찾 은 연결 도 메 인 개수 와 대응 하 는 label 을 되 돌려 줍 니 다.위의 코드 는 연결 도 메 인 개 수 를 4 로 되 돌려 줍 니 다.(포함 값 은 0 구역 이 며,lables 를 통 해 걸 러 낼 수 있 습 니 다)labels 결 과 는 그림 과 같 습 니 다.
이상 의 이 편 은 OpenCV 를 사용 하여 그림 연결 도 메 인 수량 을 얻 고 서로 다른 색상 으로 표 시 된 편 지 는 바로 작은 편집 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.여러분 께 참고 가 되 고 많은 응원 을 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Visual Studio 2017에서 OpenCV 템플릿 프로젝트 만들기・Windows 7 Professional 64bit ・Visual Studio 2017 Version 15.9.14 · OpenCV 3.4.1 OpenCV의 도입 방법 등은 아래를 참조하십시오. Visual Stu...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.