在深入探討我的問題之前,我希望您知道我已閱讀此論壇上的其他帖子,但沒有人關注我的問題。 特別是,帖子here回答了「如何做到這一點?」的問題。與k-means,雖然我已經知道我必須使用它,我想知道爲什麼我的實現不起作用。OpenCV:無法使用k-means獲得圖像分割
我想使用k-means算法根據輸入圖像的顏色將輸入圖像的像素分成多個簇。然後,在完成這樣的任務之後,我希望每個像素都具有它被分配給的集羣中心的顏色。 爲參考OpenCV的例子,在網絡上檢索到的其他的東西,我設計了下面的代碼:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat src = imread(argv[1], 1);
// reshape matrix
Mat resized(src.rows*src.cols, 3, CV_8U);
int row_counter = 0;
for(int i = 0; i<src.rows; i++)
{
for(int j = 0; j<src.cols; j++)
{
Vec3b channels = src.at<Vec3b>(i,j);
resized.at<char>(row_counter,0) = channels(0);
resized.at<char>(row_counter,1) = channels(1);
resized.at<char>(row_counter,2) = channels(2);
row_counter++;
}
}
//cout << src << endl;
// change data type
resized.convertTo(resized, CV_32F);
// determine termination criteria and number of clusters
TermCriteria criteria(TermCriteria::COUNT + TermCriteria::EPS, 10, 1.0);
int K = 8;
// apply k-means
Mat labels, centers;
double compactness = kmeans(resized, K, labels, criteria, 10, KMEANS_RANDOM_CENTERS, centers);
// change data type in centers
centers.convertTo(centers, CV_8U);
// create output matrix
Mat result = Mat::zeros(src.rows, src.cols, CV_8UC3);
row_counter = 0;
int matrix_row_counter = 0;
while(row_counter < result.rows)
{
for(int z = 0; z<result.cols; z++)
{
int index = labels.at<char>(row_counter+z, 0);
//cout << index << endl;
Vec3b center_channels(centers.at<char>(index,0),centers.at<char>(index,1), centers.at<char>(index,2));
result.at<Vec3b>(matrix_row_counter, z) = center_channels;
}
row_counter += result.cols;
matrix_row_counter++;
}
cout << "Labels " << labels.rows << " " << labels.cols << endl;
//cvtColor(src, gray, CV_BGR2GRAY);
//gray.convertTo(gray, CV_32F);
imshow("Result", result);
waitKey(0);
return 0;
}
總之,在計算快結束時,我只是得到一個黑色的圖像。 你知道爲什麼嗎? 奇怪的是,如果我在算法結束時初始化結果矩陣作爲
Mat result(src.size(), src.type())
它將顯示完全輸入圖像,沒有任何分段。
特別是,我有兩個疑惑:
1)是正確的躺在矩陣的每一行像素的RGB值調整我做的方式?有沒有辦法做到這一點沒有循環?
2)k-means函數完成工作後,中心的內容究竟是什麼?它是一個3列矩陣,它是否包含集羣中心的RGB值?
感謝您的支持。下面
可能有重複的[是否有公式確定給定BGR值的整體顏色? (OpenCV和C++)](http://stackoverflow.com/questions/34734379/is-there-a-formula-to-determine-overall-color-given-bgr-values-opencv-and-c) – Miki
感謝回答。您提供的帖子解決了我的問題,給了我一個工作代碼片段。無論如何,如果可能的話,我想知道我的錯在哪裏,因爲我幾乎肯定會在下次發生同樣的錯誤。我能否對這兩個疑問做出回答?感謝支持和抱歉,如果我問太多:) 我希望你不會把這個帖子當作經典的重複案例:) – ubisum
1)是的,正確的,但他們應該是浮動值。你可以在我的文章中看到如何做到沒有循環。 2)是的,集羣中心的BGR值以浮點數表示,需要轉換爲uchar。我現在不能更深入地看這個,但我的帖子應該清楚 – Miki