OpenCV 在图像上运行 kmeans 算法

Posted

技术标签:

【中文标题】OpenCV 在图像上运行 kmeans 算法【英文标题】:OpenCV running kmeans algorithm on an image 【发布时间】:2011-10-24 08:36:05 【问题描述】:

我正在尝试在 3 通道彩色图像上运行 kmeans,但每次我尝试运行该函数时,它似乎都会因以下错误而崩溃:

OpenCV Error: Assertion failed (data.dims <= 2 && type == CV_32F && K > 0) in unknown function, file ..\..\..\OpenCV-2.3.0\modules\core\src\matrix.cpp, line 2271

我在下面的代码中包含了一些 cmets,以帮助指定传入的内容。非常感谢任何帮助。

// Load in an image
// Depth: 8, Channels: 3
IplImage* iplImage = cvLoadImage("C:/TestImages/rainbox_box.jpg");

// Create a matrix to the image
cv::Mat mImage = cv::Mat(iplImage);

// Create a single channel image to create our labels needed
IplImage* iplLabels = cvCreateImage(cvGetSize(iplImage), iplImage->depth, 1);

// Convert the image to grayscale
cvCvtColor(iplImage, iplLabels, CV_RGB2GRAY);

// Create the matrix for the labels
cv::Mat mLabels = cv::Mat(iplLabels);

// Create the labels
int rows = mLabels.total();
int cols = 1;
cv::Mat list(rows, cols, mLabels .type());
uchar* src;
uchar* dest = list.ptr(0);
for(int i=0; i<mLabels.size().height; i++) 

    src = mLabels.ptr(i);
    memcpy(dest, src, mLabels.step);
    dest += mLabels.step;

list.convertTo(list, CV_32F);

// Run the algorithm
cv::Mat labellist(list.size(), CV_8UC1);
cv::Mat centers(6, 1, mImage.type());
cv::TermCriteria termcrit(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0);
kmeans(mImage, 6, labellist, termcrit, 3, cv::KMEANS_PP_CENTERS, centers);

【问题讨论】:

【参考方案1】:

错误说明一切Assertion failed (data.dims &lt;= 2 &amp;&amp; type == CV_32F &amp;&amp; K &gt; 0)

这些规则很容易理解,该功能只有在以下情况下才会起作用:

mImage.depth()CV_32F

如果mImage.dims&lt;= 2

如果是K &gt; 0。在这种情况下,您将 K 定义为 6

从你对问题的陈述来看,似乎是:

IplImage* iplImage = cvLoadImage("C:/TestImages/rainbox_box.jpg");` 

默认情况下将图像加载为IPL_DEPTH_8U,而不是IPL_DEPTH_32F。这意味着mImage 也是IPL_DEPTH_8U,这就是您的代码不起作用的原因。

【讨论】:

这是否意味着我必须将其作为灰度图像加载? 不,它没有。 iplImage-&gt;depthiplImage-&gt;nChannels 是两个不同的东西。您需要将 iplImage 转换为等效的 IPL_DEPTH_32F。就这样。检查这个答案如何做到这一点:***.com/questions/6349493/… 我刚刚尝试了转换功能,它在我身上崩溃了。 “IplImage* ipl32Image = cvCreateImage(cvGetSize(iplImage), IPL_DEPTH_32F, 1); cvConvert(iplImage, ipl32Image);”在未知函数中出现错误“OpenCV 错误:断言失败 (src.size == dst.size && src.channels() == dst.ch annels()),文件 ..\..\..\OpenCV-2.3 .0\modules\core\src\convert.cpp,第 1177 行”。看来我要么必须拆分通道,要么必须加载灰度图像 崩溃是因为你假设iplImage的通道数是1。修复它为cvCreateImage(cvGetSize(iplImage), IPL_DEPTH_32F, iplImage-&gt;nChannels); 漂亮!我误解了“mImage.dims”,认为它只希望它是 1 或 2。非常感谢。 :D

以上是关于OpenCV 在图像上运行 kmeans 算法的主要内容,如果未能解决你的问题,请参考以下文章

如何加快openCV中的颜色聚类?

如何在opencv中访问特定的kmeans集群

opencv c++ kmeans 和 matlab kmeans 的不同结果

opencv::基于距离变换与分水岭的图像分割

基于K-means聚类算法的图像分割

opencv:如何使用kmeans()按角度聚类