2016-01-12 10 views
7

Tworzę funkcję za pomocą C++ i OpenCV, która wykrywa kolor piksela na obrazku, określa zakres kolorów, w którym on się znajduje i zastępuje go kolorem ogólnym. Na przykład kolor zielony może być w zakresie od ciemnozielonego do jasnozielonego, program określi, że nadal jest zielony i zastępuje go prostym zielonym, co sprawia, że ​​obraz wyjściowy wygląda bardzo prosto. wszystko jest ustawione, ale mam problem z określeniem charakterystyki każdego zakresu i byłem ciekawy, czy ktoś wie, czy też formuła, która, biorąc pod uwagę wartości BGR, mogłaby określić ogólny kolor piksela. Jeśli nie, będę musiał dużo eksperymentować i zrobić to sam, ale jeśli coś już istnieje, zaoszczędziłoby to czasu. Zrobiłem wiele badań i nie znalazłem nic do tej pory.Czy istnieje wzór do określenia ogólnego koloru z podanymi wartościami BGR? (OpenCV i C++)

+0

„ogólny kolor piksela "jest nieco niejasny - czy istnieje stała liczba kolorów, do których chcesz zamapować wszystkie kolory? Można podzielić każdą przestrzeń kolorów na k różnych wartości, aby utworzyć małą przestrzeń, którą można oznaczyć.'int three_reds = int (floor (R/3)); ... "Można wtedy po prostu odwzorować każdy zakres na pojedynczy kolor z przestrzeni RGB. – Pyrce

+0

Chociaż istnieją tysiące sposobów, aby to zrobić, niektóre znacznie lepiej niż inne, uważam, że powinieneś był być w stanie wymyślić przynajmniej podstawową implementację, gdy zobaczysz ideę kostki kolorów. 8 kolorów narożników to czarno-białe, czyste RGB i uzupełniające się kolory. (więc wszystkie 6 kolorów tęczy). Po prostu wybieranie najbliższego rogu dałoby ci coś do pokazania. – MSalters

+0

Istnieje kilka. Sprawdź "kwantyzację koloru". – beaker

Odpowiedz

4

Tak, co prawdopodobnie znaczy „Ogólny kolor piksela” jest albo "Hue" or "Saturation" of the color.

Więc chcesz formułę przekształcenia RGB do HSV (Hue, Saturation, Value), a potem będzie tylko zainteresowany wartościami Barwy lub Nasycenia.

Patrz: Algorithm to convert RGB to HSV and HSV to RGB in range 0-255 for both

EDIT: Być może trzeba do max obecnie nasycenia, a następnie przekształcić go z powrotem do RGB, i sprawdzić, która wartość jest najwyższa (na przykład (255,0,0) lub (255,0,255) itd

12

Jeśli chcesz, aby Twoje zdjęcie prostsze (czyli z mniej kolorów), ale przystojny, masz kilka opcji:

  • prostym rozwiązaniem byłoby podzielić (z podziałem całkowitym) przez współczynnik N obrazu, a następnie pomnożyć przez współczynnik N.

  • Możesz podzielić swój obraz na kolory K, korzystając z algorytmu grupowania, takiego jak kmeans, pokazanego tutaj, lub algorytmu wycięcia mediany.

oryginalny obraz:

enter image description here

Zmniejszone kolorów (kwantyzowane N = 64)

enter image description here

Zmniejszone kolorów (klastrowych K = 8):

enter image description here

Kod kwantyzacji:

#include <opencv2/opencv.hpp> 
using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat3b img = imread("path_to_image"); 

    imshow("Original", img); 

    uchar N = 64; 
    img /= N; 
    img *= N; 

    imshow("Reduced", img); 
    waitKey(); 

    return 0; 
} 

kmeans Kod:

#include <opencv2/opencv.hpp> 
using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat3b img = imread("path_to_image"); 

    imshow("Original", img); 

    // Cluster 

    int K = 8; 
    int n = img.rows * img.cols; 
    Mat data = img.reshape(1, n); 
    data.convertTo(data, CV_32F); 

    vector<int> labels; 
    Mat1f colors; 
    kmeans(data, K, labels, cv::TermCriteria(), 1, cv::KMEANS_PP_CENTERS, colors); 

    for (int i = 0; i < n; ++i) 
    { 
     data.at<float>(i, 0) = colors(labels[i], 0); 
     data.at<float>(i, 1) = colors(labels[i], 1); 
     data.at<float>(i, 2) = colors(labels[i], 2); 
    } 

    Mat reduced = data.reshape(3, img.rows); 
    reduced.convertTo(reduced, CV_8U); 


    imshow("Reduced", reduced); 
    waitKey(); 

    return 0; 
} 
+0

Stodoła Moulton <3 – bcrist

-1

Jeśli chcesz uzyskać dostęp do wartości RGB wszystkich pikseli, a następnie poniżej jest kod,

#include <opencv2/opencv.hpp> 
using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat image = imread("image_path"); 

    for(int row = 1; row < image.rows; row++) 
    { 
     for(int col = 1; col < image.cols; col++) 
     { 
      Vec3b rgb = image.at<Vec3b>(row, col); 
     } 
    } 

} 
Powiązane problemy