una procesamiento pixeles negativo los lenguaje imagenes imagen grises escala con acceder c++ opencv visual-c++ opencv3.0

pixeles - procesamiento de imagenes en c++



¿Cómo obtener la paleta de colores de la imagen usando opencv? (1)

Me gustaría extraer la paleta de colores de una imagen, similar a esta (desde here ):

Lo necesito para extraer colores específicos como amarillo, verde y marrón y mostrar el porcentaje del área cubierta por ese color. Además, puedo agregar más colores para extraer.

¿Cómo puedo reducir la cantidad de colores en la imagen original y cómo puedo obtener la paleta de colores?


Hay 3 cosas diferentes pasando aquí.

  1. Reduce la cantidad de colores de una imagen
  2. Obtén los diferentes colores de una imagen
  3. Obtén el nombre del color

Reduce la cantidad de colores

Existen muchas técnicas para reducir la cantidad de colores. Here puede ver cómo usar la cuantización del color y los kmeans .

Otro enfoque podría usar el algoritmo Median Cut (no se muestra aquí).

OpenCV proporciona el module renderizado no fotorrealista . Here puede ver algunos ejemplos sobre cómo usarlo.

Obtén los diferentes colores de una imagen

Esto es bastante facil. Simplemente itera sobre toda la imagen. Si ve un nuevo color, almacene su valor, con un contador igual a 1. Si ve un color ya visto, incremente su contador. Un std::map podría ser útil aquí.

Obtén el nombre del color

No lo mostraré aquí. Pero en línea hay algunos recursos útiles . Necesita una lista de todos los colores con nombre. Tenga en cuenta que no todos los colores tienen un nombre. De hecho, todos los colores posibles para valores RGB serían 256*256*256 . Así que encuentre el color más cercano en su lista y asigne su nombre a su color actual.

Por ejemplo, con esta imagen de entrada:

usando el enfoque kmeans obtengo la imagen de color reducida :

y su paleta es:

Color: [14, 134, 225] - Area: 5.28457% Color: [16, 172, 251] - Area: 27.3851% Color: [22, 68, 101] - Area: 3.41029% Color: [28, 154, 161] - Area: 3.89029% Color: [40, 191, 252] - Area: 22.3429% Color: [87, 204, 251] - Area: 8.704% Color: [161, 222, 251] - Area: 3.47429% Color: [253, 255, 255] - Area: 25.5086%

Ahora puede buscar el nombre de color más cercano en su lista y obtendrá lo que necesita. Cómo inventariar la GUI para mostrar esta información depende de usted: todos los datos están ahí.

Código:

#include <opencv2/opencv.hpp> #include <opencv2/photo.hpp> #include <iostream> #include <map> using namespace cv; using namespace std; // https://.com/a/34734939/5008845 void reduceColor_Quantization(const Mat3b& src, Mat3b& dst) { uchar N = 64; dst = src / N; dst *= N; } // https://.com/a/34734939/5008845 void reduceColor_kmeans(const Mat3b& src, Mat3b& dst) { int K = 8; int n = src.rows * src.cols; Mat data = src.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, src.rows); reduced.convertTo(dst, CV_8U); } void reduceColor_Stylization(const Mat3b& src, Mat3b& dst) { stylization(src, dst); } void reduceColor_EdgePreserving(const Mat3b& src, Mat3b& dst) { edgePreservingFilter(src, dst); } struct lessVec3b { bool operator()(const Vec3b& lhs, const Vec3b& rhs) { return (lhs[0] != rhs[0]) ? (lhs[0] < rhs[0]) : ((lhs[1] != rhs[1]) ? (lhs[1] < rhs[1]) : (lhs[2] < rhs[2])); } }; map<Vec3b, int, lessVec3b> getPalette(const Mat3b& src) { map<Vec3b, int, lessVec3b> palette; for (int r = 0; r < src.rows; ++r) { for (int c = 0; c < src.cols; ++c) { Vec3b color = src(r, c); if (palette.count(color) == 0) { palette[color] = 1; } else { palette[color] = palette[color] + 1; } } } return palette; } int main() { Mat3b img = imread("path_to_image"); // Reduce color Mat3b reduced; //reduceColor_Quantization(img, reduced); reduceColor_kmeans(img, reduced); //reduceColor_Stylization(img, reduced); //reduceColor_EdgePreserving(img, reduced); // Get palette map<Vec3b, int, lessVec3b> palette = getPalette(reduced); // Print palette int area = img.rows * img.cols; for (auto color : palette) { cout << "Color: " << color.first << " /t - Area: " << 100.f * float(color.second) / float(area) << "%" << endl; } return 0; }