정답 cv::Mat inputSamples(numSamples, numFeatures, CV_32F)
이다 이것은 :
cv::Mat inputSamples(numSamples, 1, CV32FC(numFeatures))
또는 이와 I은 5 차원의 특징 벡터가있는 경우
, 어떻게 I가 사용하는 입력 행렬이어야 . OpenCV의 문서에 대한 kmeans
says :
샘플 - 입력 샘플들의 부동 소수점 행렬 샘플 당 하나의 행
그래서 같이 N 차원 플로트 부동 소수점 벡터가 아닌 다른 옵션. 어떤 예가 그러한 행동을 제안 했습니까?
kmeans의 사용법을 보여주는 나에게도 작은 예제가 있습니다. 이는 이미지의 픽셀 클러스터 및 결과를 표시 수동 입력 행렬을 재 형성에 대한 대안으로서, 적은 코드와 유사한 결과를 얻을 OpenCV의 reshape 기능을 사용할 수
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int main(int argc, char** argv)
{
Mat src = imread(argv[1], 1);
Mat samples(src.rows * src.cols, 3, CV_32F);
for(int y = 0; y < src.rows; y++)
for(int x = 0; x < src.cols; x++)
for(int z = 0; z < 3; z++)
samples.at<float>(y + x*src.rows, z) = src.at<Vec3b>(y,x)[z];
int clusterCount = 15;
Mat labels;
int attempts = 5;
Mat centers;
kmeans(samples, clusterCount, labels, TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10000, 0.0001), attempts, KMEANS_PP_CENTERS, centers);
Mat new_image(src.size(), src.type());
for(int y = 0; y < src.rows; y++)
for(int x = 0; x < src.cols; x++)
{
int cluster_idx = labels.at<int>(y + x*src.rows,0);
new_image.at<Vec3b>(y,x)[0] = centers.at<float>(cluster_idx, 0);
new_image.at<Vec3b>(y,x)[1] = centers.at<float>(cluster_idx, 1);
new_image.at<Vec3b>(y,x)[2] = centers.at<float>(cluster_idx, 2);
}
imshow("clustered image", new_image);
waitKey(0);
}
나는 clusterCount 변수 선언 전에 루프에서 무엇을하고 있는지, 그리고 kmeans 후에 for의 끝에 무엇을하고 있는지 알고 싶습니다. 이 정보로 답변을 업데이트 할 수 있다고 생각하십니까? 감사! –
첫 번째 루프는 (rows, cols, 3) 행렬에서 (rows * cols, 3) 행렬 (픽셀 당 하나의 행)까지 이미지의 데이터를 재정렬합니다. 끝에있는 루프는 이미지의 각 픽셀을 시각화를 위해 해당 클러스터 중심으로 대체합니다. – sietschie
for 중첩 된 루프 대신'Mat :: reshape()'를 사용할 수 있습니까? – Jayesh