using OpenCvSharp;
namespace demo
{
internal class Program
{
static void Main(string[] args)
{
var src = new Mat(@"../../../images/fruits.jpg", ImreadModes.AnyDepth | ImreadModes.AnyColor);
Cv2.ImShow("Source", src);
Cv2.WaitKey(1); // do events
Cv2.Blur(src, src, new Size(15, 15));
Cv2.ImShow("Blurred Image", src);
Cv2.WaitKey(1); // do events
// Converts the MxNx3 image into a Kx3 matrix where K=MxN and
// each row is now a vector in the 3-D space of RGB.
// change to a Mx3 column vector (M is number of pixels in image)
var columnVector = src.Reshape(cn: 3, rows: src.Rows * src.Cols);
// convert to floating point, it is a requirement of the k-means method of OpenCV.
var samples = new Mat();
columnVector.ConvertTo(samples, MatType.CV_32FC3);
TermCriteria criteria = new TermCriteria(type: CriteriaTypes.Eps | CriteriaTypes.MaxIter, maxCount: 10, epsilon: 1.0);
int K = 2; // 2、4、6、8
var bestLabels = new Mat();
var centers = new Mat();
Cv2.Kmeans(
data: samples,
k: K,
bestLabels: bestLabels,
criteria: criteria,
attempts: 3,
flags: KMeansFlags.PpCenters,
centers: centers);
var clusteredImage = new Mat(src.Rows, src.Cols, src.Type());
for (var size = 0; size < src.Cols * src.Rows; size++)
{
var clusterIndex = bestLabels.At<int>(0, size);
var newPixel = new Vec3b
{
Item0 = (byte)(centers.At<float>(clusterIndex, 0)), // B
Item1 = (byte)(centers.At<float>(clusterIndex, 1)), // G
Item2 = (byte)(centers.At<float>(clusterIndex, 2)) // R
};
clusteredImage.Set(size / src.Cols, size % src.Cols, newPixel);
}
Cv2.ImShow(string.Format("Clustered Image [k:{0}]", K), clusteredImage);
Cv2.ImWrite("out.jpg", clusteredImage);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
}
}
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat src = cv::imread("../images/fruits.jpg");
cv::imshow("Source", src);
cv::waitKey(1); // do events
cv::blur(src, src, Size(15, 15));
cv::imshow("Blurred Image", src);
cv::waitKey(1); // do events
// Converts the MxNx3 image into a Kx3 matrix where K=MxN and
// each row is now a vector in the 3-D space of RGB.
// change to a Mx3 column vector (M is number of pixels in image)
Mat columnVector = src.reshape(3, src.rows * src.cols);
// convert to floating point, it is a requirement of the k-means method of OpenCV.
Mat samples;
columnVector.convertTo(samples, CV_32FC3);
TermCriteria criteria = TermCriteria(TermCriteria::EPS | TermCriteria::MAX_ITER, 10, 1.0);
int K = 2; // 2、4、6、8
Mat bestLabels;
Mat centers;
cv::kmeans(samples, K, bestLabels, criteria, 3, KmeansFlags::KMEANS_PP_CENTERS, centers);
//create a color map
std::vector<cv::Scalar> colorMaps;
uchar b, g, r;;
//clusterCount is equal to centers.rows
for (int i = 0; i < centers.rows; i++)
{
b = (uchar)centers.at<float>(i, 0);
g = (uchar)centers.at<float>(i, 1);
r = (uchar)centers.at<float>(i, 2);
colorMaps.push_back(cv::Scalar(b, g, r));
}
// Show result
int index = 0;
Mat clusteredImage(src.rows, src.cols, src.type());
uchar* ptr = NULL;
int* label = NULL;
for (int row = 0; row < src.rows; row++) {
ptr = clusteredImage.ptr<uchar>(row);
for (int col = 0; col < src.cols; col++) {
index = row * src.cols + col;
label = bestLabels.ptr<int>(index);
*(ptr + col * 3) = colorMaps[*label][0];
*(ptr + col * 3 + 1) = colorMaps[*label][1];
*(ptr + col * 3 + 2) = colorMaps[*label][2];
}
}
cv::imshow("Clustered Image", clusteredImage);
cv::waitKey();
cv::destroyAllWindows();
}
Python版本代码如下:
demo1:颜色量化
源码如下:
import numpy as np
import cv2
img = cv2.imread('../images/fruits.jpg')
# img = cv2.imread('../data/opencv_logo.png')
Z = img.reshape((-1, 3))
# convert to np.float32
Z = np.float32(Z)
# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# K = 8
# K = 3
K = 14
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# Now convert back into uint8, and make original image
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
cv2.imshow('res2', res2)
cv2.waitKey(0)
cv2.destroyAllWindows()
demo2:颜色量化,分离
import numpy as np
import cv2
img = cv2.imread('../images/fruits.jpg')
# img = cv2.imread('../data/opencv_logo.png')
Z = img.reshape((-1, 3))
# convert to np.float32
Z = np.float32(Z)
# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8
# K = 3
# K = 14
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# 分离颜色
for y in range(len(center)):
a1 = []
for i, x in enumerate(label.ravel()):
if x == y:
a1.append(list(Z[i]))
else:
a1.append([0, 0, 0])
a2 = np.array(a1)
a3 = a2.reshape((img.shape))
cv2.imshow('res2' + str(y), a3)
# 最大的色块
# # Now convert back into uint8, and make original image
# center = np.uint8(center)
# res = center[label.flatten()]
# res2 = res.reshape((img.shape))
# cv2.imshow('res2', res2)
# cv2.imshow('res2', a3)
cv2.waitKey(0)
cv2.destroyAllWindows()
using OpenCvSharp;
namespace demo
{
internal class Program
{
static void Main(string[] args)
{
var src = new Mat(@"../../../images/fruits.jpg", ImreadModes.AnyDepth | ImreadModes.AnyColor);
Cv2.ImShow("Source", src);
Cv2.WaitKey(1); // do events
Cv2.Blur(src, src, new Size(15, 15));
Cv2.ImShow("Blurred Image", src);
Cv2.WaitKey(1); // do events
// Converts the MxNx3 image into a Kx3 matrix where K=MxN and
// each row is now a vector in the 3-D space of RGB.
// change to a Mx3 column vector (M is number of pixels in image)
var columnVector = src.Reshape(cn: 3, rows: src.Rows * src.Cols);
// convert to floating point, it is a requirement of the k-means method of OpenCV.
var samples = new Mat();
columnVector.ConvertTo(samples, MatType.CV_32FC3);
TermCriteria criteria = new TermCriteria(type: CriteriaTypes.Eps | CriteriaTypes.MaxIter, maxCount: 10, epsilon: 1.0);
int K = 2; // 2、4、6、8
var bestLabels = new Mat();
var centers = new Mat();
Cv2.Kmeans(
data: samples,
k: K,
bestLabels: bestLabels,
criteria: criteria,
attempts: 3,
flags: KMeansFlags.PpCenters,
centers: centers);
var clusteredImage = new Mat(src.Rows, src.Cols, src.Type());
for (var size = 0; size < src.Cols * src.Rows; size++)
{
var clusterIndex = bestLabels.At<int>(0, size);
var newPixel = new Vec3b
{
Item0 = (byte)(centers.At<float>(clusterIndex, 0)), // B
Item1 = (byte)(centers.At<float>(clusterIndex, 1)), // G
Item2 = (byte)(centers.At<float>(clusterIndex, 2)) // R
};
clusteredImage.Set(size / src.Cols, size % src.Cols, newPixel);
}
Cv2.ImShow(string.Format("Clustered Image [k:{0}]", K), clusteredImage);
Cv2.ImWrite("out.jpg", clusteredImage);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
}
}
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat src = cv::imread("../images/fruits.jpg");
cv::imshow("Source", src);
cv::waitKey(1); // do events
cv::blur(src, src, Size(15, 15));
cv::imshow("Blurred Image", src);
cv::waitKey(1); // do events
// Converts the MxNx3 image into a Kx3 matrix where K=MxN and
// each row is now a vector in the 3-D space of RGB.
// change to a Mx3 column vector (M is number of pixels in image)
Mat columnVector = src.reshape(3, src.rows * src.cols);
// convert to floating point, it is a requirement of the k-means method of OpenCV.
Mat samples;
columnVector.convertTo(samples, CV_32FC3);
TermCriteria criteria = TermCriteria(TermCriteria::EPS | TermCriteria::MAX_ITER, 10, 1.0);
int K = 2; // 2、4、6、8
Mat bestLabels;
Mat centers;
cv::kmeans(samples, K, bestLabels, criteria, 3, KmeansFlags::KMEANS_PP_CENTERS, centers);
//create a color map
std::vector<cv::Scalar> colorMaps;
uchar b, g, r;;
//clusterCount is equal to centers.rows
for (int i = 0; i < centers.rows; i++)
{
b = (uchar)centers.at<float>(i, 0);
g = (uchar)centers.at<float>(i, 1);
r = (uchar)centers.at<float>(i, 2);
colorMaps.push_back(cv::Scalar(b, g, r));
}
// Show result
int index = 0;
Mat clusteredImage(src.rows, src.cols, src.type());
uchar* ptr = NULL;
int* label = NULL;
for (int row = 0; row < src.rows; row++) {
ptr = clusteredImage.ptr<uchar>(row);
for (int col = 0; col < src.cols; col++) {
index = row * src.cols + col;
label = bestLabels.ptr<int>(index);
*(ptr + col * 3) = colorMaps[*label][0];
*(ptr + col * 3 + 1) = colorMaps[*label][1];
*(ptr + col * 3 + 2) = colorMaps[*label][2];
}
}
cv::imshow("Clustered Image", clusteredImage);
cv::waitKey();
cv::destroyAllWindows();
}
Python版本代码如下:
demo1:颜色量化
源码如下:
import numpy as np
import cv2
img = cv2.imread('../images/fruits.jpg')
# img = cv2.imread('../data/opencv_logo.png')
Z = img.reshape((-1, 3))
# convert to np.float32
Z = np.float32(Z)
# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# K = 8
# K = 3
K = 14
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# Now convert back into uint8, and make original image
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
cv2.imshow('res2', res2)
cv2.waitKey(0)
cv2.destroyAllWindows()
demo2:颜色量化,分离
import numpy as np
import cv2
img = cv2.imread('../images/fruits.jpg')
# img = cv2.imread('../data/opencv_logo.png')
Z = img.reshape((-1, 3))
# convert to np.float32
Z = np.float32(Z)
# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8
# K = 3
# K = 14
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# 分离颜色
for y in range(len(center)):
a1 = []
for i, x in enumerate(label.ravel()):
if x == y:
a1.append(list(Z[i]))
else:
a1.append([0, 0, 0])
a2 = np.array(a1)
a3 = a2.reshape((img.shape))
cv2.imshow('res2' + str(y), a3)
# 最大的色块
# # Now convert back into uint8, and make original image
# center = np.uint8(center)
# res = center[label.flatten()]
# res2 = res.reshape((img.shape))
# cv2.imshow('res2', res2)
# cv2.imshow('res2', a3)
cv2.waitKey(0)
cv2.destroyAllWindows()