2016-01-12 10 views
7

Sto facendo una funzione utilizzando C++ e OpenCV che rilevano il colore di un pixel in un'immagine, determinano in quale intervallo di colori si trova e lo sostituiscono con un colore generico. Ad esempio, il verde potrebbe variare da verde scuro a verde chiaro, il programma determinerebbe che è ancora verde e sostituirlo con un semplice verde, rendendo l'immagine di output molto semplice. tutto è impostato ma ho problemi a definire le caratteristiche di ogni intervallo ed ero curioso di sapere se qualcuno o una formula che, dati i valori BGR, potesse determinare il colore complessivo di un pixel. Altrimenti dovrò fare molta sperimentazione e realizzarla da sola, ma se esiste già qualcosa che farebbe risparmiare tempo. Ho fatto molte ricerche e non ho trovato nulla finora.Esiste una formula per determinare il colore complessivo in base ai valori BGR? (OpenCV e C++)

+0

'complessiva il colore di un pixel 'è un po' vago - c'è un numero fisso di colori in cui vuoi mappare tutti i colori? Puoi dividere ogni spazio cromatico in k valori distinti per creare un piccolo spazio che puoi etichettare.'int three_reds = int (floor (R/3)); ... 'È quindi possibile mappare ogni intervallo a un singolo colore dallo spazio RGB. – Pyrce

+0

Mentre ci sono migliaia di modi per farlo, alcuni molto meglio di altri, credo che avresti dovuto essere in grado di realizzare almeno un'implementazione di base una volta che hai visto l'idea di un cubo di colore. Gli 8 colori degli angoli sono in bianco e nero, RGB puro e i colori complementari. (quindi tutti e 6 i colori dell'arcobaleno). Scegliere l'angolo più vicino ti avrebbe dato qualcosa da mostrare. – MSalters

+0

Ce ne sono diversi. Cerca "quantizzazione del colore". – beaker

risposta

4

Sì, quello che probabilmente intende per "Il colore generale di un pixel" è o il "Hue" or "Saturation" of the color.

Così si desidera un formula che trasforma RGB per HSV (tonalità, saturazione, valore), e quindi si sarebbe solo interessati dai valori di tonalità o saturazione.

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

EDIT: Potrebbe essere necessario al massimo fuori la saturazione, e poi riconvertirlo in RGB, e controllare che il valore è il più alto (per esempio (255,0,0), o (255,0,255), ecc

12

Se si desidera rendere la vostra immagine semplice (cioè con meno colori), ma bello, avete alcune opzioni:

  • Un approccio semplice sarebbe dividere (divisione intera) da un fattore N l'immagine e quindi moltiplicare per un fattore N.

  • Oppure è possibile dividere l'immagine in K colori, utilizzando un algoritmo di clustering come kmeans mostrato qui o algoritmo di taglio mediano.

immagine originale:

enter image description here

colori Ridotto (quantizzati, N = 64):

enter image description here

colori Ridotto (cluster, K = 8):

enter image description here

Codice quantizzazione:

#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 codice:

#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

Granaio di Moulton <3 – bcrist

-1

Se si desidera accedere valore RGB di tutti i pixel, quindi di seguito è il codice,

#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); 
     } 
    } 

} 
Problemi correlati