gpt4 book ai didi

c++ - OpenCV:无法使用 k-means 进行图像分割

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:45:29 25 4
gpt4 key购买 nike

在深入探讨我的问题之前,我想让您知道我已经阅读了该论坛上的其他帖子,但没有人关注我的问题。特别是帖子 here回答“如何做到这一点?”的问题使用 k-means,虽然我已经知道我必须使用它,但我想知道为什么我的实现不起作用。

我想使用 k-means 算法根据颜色将输入图像的像素分成簇。然后,在完成这样的任务后,我希望每个像素都具有它所分配到的集群中心的颜色。引用网上的 OpenCV 示例和其他资料,我设计了以下代码:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace std;
using namespace cv;


int main( int argc, char** argv )
{

Mat src = imread( argv[1], 1 );

// reshape matrix
Mat resized(src.rows*src.cols, 3, CV_8U);
int row_counter = 0;

for(int i = 0; i<src.rows; i++)
{
for(int j = 0; j<src.cols; j++)
{
Vec3b channels = src.at<Vec3b>(i,j);
resized.at<char>(row_counter,0) = channels(0);
resized.at<char>(row_counter,1) = channels(1);
resized.at<char>(row_counter,2) = channels(2);

row_counter++;
}
}

//cout << src << endl;

// change data type
resized.convertTo(resized, CV_32F);

// determine termination criteria and number of clusters
TermCriteria criteria(TermCriteria::COUNT + TermCriteria::EPS, 10, 1.0);
int K = 8;

// apply k-means
Mat labels, centers;
double compactness = kmeans(resized, K, labels, criteria, 10, KMEANS_RANDOM_CENTERS, centers);

// change data type in centers
centers.convertTo(centers, CV_8U);

// create output matrix
Mat result = Mat::zeros(src.rows, src.cols, CV_8UC3);

row_counter = 0;
int matrix_row_counter = 0;
while(row_counter < result.rows)
{
for(int z = 0; z<result.cols; z++)
{
int index = labels.at<char>(row_counter+z, 0);
//cout << index << endl;
Vec3b center_channels(centers.at<char>(index,0),centers.at<char>(index,1), centers.at<char>(index,2));
result.at<Vec3b>(matrix_row_counter, z) = center_channels;
}

row_counter += result.cols;
matrix_row_counter++;
}

cout << "Labels " << labels.rows << " " << labels.cols << endl;
//cvtColor( src, gray, CV_BGR2GRAY );
//gray.convertTo(gray, CV_32F);

imshow("Result", result);
waitKey(0);


return 0;
}

无论如何,在计算结束时,我只是得到一张黑色图像。你知道为什么吗?奇怪的是,如果我将 result 矩阵初始化为

Mat result(src.size(), src.type())

在算法结束时,它将准确显示输入图像,不进行任何分割。

具体来说,我有两个疑惑:

1) 按照我所做的resized 矩阵的每一行放置像素的 RGB 值是否正确?有没有没有循环的方法?

2) 在 k-means 函数完成工作后,centers 的内容到底是什么?它是一个 3 列矩阵,它是否包含簇中心的 RGB 值?

感谢支持。

最佳答案

-下面发布的 OpenCV 程序将用户首选颜色分配给图像中的特定像素值

- ScanImageAndReduceC()是 OpenCV 中预定义的扫描图像所有像素的方法

- I.atuchar>(10, 10) = 255; 用于访问图像的特定像素值

代码如下:


Mat& ScanImageAndReduceC(Mat& I)
{



<p>// accept only char type matrices
<code>CV_Assert(I.depth() == CV_8U);</code></p><code>

</code><pre><code>int channels = I.channels();

int nRows = I.rows;
int nCols = I.cols * channels;

if (I.isContinuous())
{
nCols *= nRows;
nRows = 1;
}

int i, j;
uchar* p;
for (i = 0; i < nRows; ++i)
{
p = I.ptr<uchar>(i);
for (j = 0; j < nCols; ++j)
{
I.at<uchar>(10, 10) = 255;
}
}
return I;
</code></pre>

<p>}</p>

<p>-------Main Program-------</p>

<p><i> <b> Calling the above method in our main program</b></i></p>

diff = ScanImageAndReduceC(diff);

namedWindow("Difference", WINDOW_AUTOSIZE);// Create a window for display.
imshow("Difference", diff); // Show our image inside it.

waitKey(0); // Wait for a keystroke in the window
return 0;

关于c++ - OpenCV:无法使用 k-means 进行图像分割,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39612545/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com