Chcę posteryzować obraz za pomocą k-średnich i OpenCV w interfejsie C++ (przestrzeń nazw cv) i otrzymuję dziwne wyniki. Potrzebuję go, aby zmniejszyć hałas. To jest mój kod:OpenCV przy użyciu k-środków do posteryzacji obrazu
#include "cv.h"
#include "highgui.h"
using namespace cv;
int main() {
Mat imageBGR, imageHSV, planeH, planeS, planeV;
imageBGR = imread("fruits.jpg");
imshow("original", imageBGR);
cv::Mat labels, data;
cv::Mat centers(8, 1, CV_32FC1);
imageBGR.convertTo(data, CV_32F);
cv::kmeans(data, 8, labels,
cv::TermCriteria(CV_TERMCRIT_ITER, 10, 1.0),
3, cv::KMEANS_PP_CENTERS, ¢ers);
imshow("posterized hue", data);
data.convertTo(data, CV_32FC3);
waitKey();
return 0;
}
Ale mam dziwne Wynik
Pierwszy obraz: oryginalna
Drugi obraz: po k-średnich.
Każda rada?
Aktualizacja: odpowiednie rozwiązanie. może ktoś może mi pomóc w optymalizacji kodu?
#include "cv.h"
#include "highgui.h"
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat src;
src = imread("fruits.jpg");
imshow("original", src);
blur(src, src, Size(15,15));
imshow("blurred", src);
Mat p = Mat::zeros(src.cols*src.rows, 5, CV_32F);
Mat bestLabels, centers, clustered;
vector<Mat> bgr;
cv::split(src, bgr);
// i think there is a better way to split pixel bgr color
for(int i=0; i<src.cols*src.rows; i++) {
p.at<float>(i,0) = (i/src.cols)/src.rows;
p.at<float>(i,1) = (i%src.cols)/src.cols;
p.at<float>(i,2) = bgr[0].data[i]/255.0;
p.at<float>(i,3) = bgr[1].data[i]/255.0;
p.at<float>(i,4) = bgr[2].data[i]/255.0;
}
int K = 8;
cv::kmeans(p, K, bestLabels,
TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),
3, KMEANS_PP_CENTERS, centers);
int colors[K];
for(int i=0; i<K; i++) {
colors[i] = 255/(i+1);
}
// i think there is a better way to do this mayebe some Mat::reshape?
clustered = Mat(src.rows, src.cols, CV_32F);
for(int i=0; i<src.cols*src.rows; i++) {
clustered.at<float>(i/src.cols, i%src.cols) = (float)(colors[bestLabels.at<int>(0,i)]);
// cout << bestLabels.at<int>(0,i) << " " <<
// colors[bestLabels.at<int>(0,i)] << " " <<
// clustered.at<float>(i/src.cols, i%src.cols) << " " <<
// endl;
}
clustered.convertTo(clustered, CV_8U);
imshow("clustered", clustered);
waitKey();
return 0;
}
Wynik:
może po prostu, że trzeba więcej iteracji i/lub mniejszy epsilon. Proponuję teraz spróbować usunąć "CV_TERMCRIT_EPS" i grać z liczbą iteracji w TermCriteria. Sprawdź, czy to pomaga. –
Właśnie zbliżam się do wizji komputerowej, przetwarzania obrazu i uczenia maszynowego, ale dla mnie jest inny błąd w tym, co robię, a nie tylko parametr dostrajania .. – nkint
Nie sugeruję, abyś zaczął dostrajanie parametru, jestem sugerując uproszczenie kodu w celu sprawdzenia, czy to, co próbujesz, działa w jego najbardziej podstawowej formie. Usunięcie epsilon i zwiększenie liczby iteracji usuwa niepotrzebne oszustwa. –