记录一次c++实现图片颜色聚类的小需求
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录一次c++实现图片颜色聚类的小需求相关的知识,希望对你有一定的参考价值。
安装visual studio 2019
安装c++的IDE Visual Studio 2019安装与使用
配置opencv环境
VS配置OpenCV开发环境(c++):How & Whywindows下OpenCV的安装配置部署详细教程
代码
python实现的核心代码(这里读取的是四图层图片)
def image_process(img, o_path, p):
# 图像二维像素转换为一维
# 转换成3列
data = img[:, :, :3].reshape((-1, 3))
data = np.float32(data)
# 定义终止条件 (type,max_iter,epsilon)
criteria = (cv2.TERM_CRITERIA_EPS +
cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# 设置初始中心的选择
# flags = cv2.KMEANS_RANDOM_CENTERS
flags = cv2.KMEANS_PP_CENTERS
# K-Means聚类 聚集成4类
compactness, labels, centers = cv2.kmeans(data, 9, None, criteria, 10, flags)
# 图像转换回uint8二维类型
# centers = np.uint8(centers)
# new_colour 对中心点做了变换,可以直接使用聚类的中心点结果
new_centers = new_colour(centers)
# print(centers)
# print(new_centers)
res = new_centers[labels.flatten()]
# res = centers[labels.flatten()]
dst = res.reshape(img[:, :, :3].shape)
dst = np.concatenate((dst, img[:, :, 3:]), axis=2)
cv2.imwrite(os.path.join(o_path, p), dst)
c++
Mat colourProcess(Mat& img, int nums)
if (img.empty())
return img;
int width = img.cols;
int height = img.rows;
int dims = img.channels();
int sampleCount = width * height;
Mat points(sampleCount, dims, CV_32F, Scalar());
Mat labels;
Mat centers(nums, 1, points.type());
int index = 0;
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++)
index = row * width + col;
Vec3b bgr = img.at<Vec3b>(row, col);
points.at<float>(index, 0) = static_cast<int>(bgr[0]);
points.at<float>(index, 1) = static_cast<int>(bgr[1]);
points.at<float>(index, 2) = static_cast<int>(bgr[2]);
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1);
kmeans(points, nums, labels, criteria, 3, KMEANS_PP_CENTERS, centers);
//cout << centers.at<Vec3f>(0) << endl;
//cout << centers.rows << << centers.cols << endl;
//cout << centers << endl;
vector<int> vi = calNewCenters(centers, img);
for (auto i : vi)
cout << colorTab[i] << endl;
Mat result = Mat::zeros(img.size(), img.type());
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++)
index = row * width + col;
int label = labels.at<int>(index, 0);
result.at<Vec3b>(row, col)[0] = colorTab[vi[label]][0];
result.at<Vec3b>(row, col)[1] = colorTab[vi[label]][1];
result.at<Vec3b>(row, col)[2] = colorTab[vi[label]][2];
return result;
参考
Opencv之是什么东东python OpenCV 中 Kmeans 函数详解
opencv kmeans聚类 图像色彩量化为例
opencv KMeans 图像分割实例
OpenCV如何实现透明(alpha channel)图像的读取和写入
以上是关于记录一次c++实现图片颜色聚类的小需求的主要内容,如果未能解决你的问题,请参考以下文章