[英]How to convert image (Mat) into inputArray in C++ OpenCV?
I want to apply k-means clustering on the intensity values of a grayscale image. 我想对灰度图像的强度值应用k均值聚类。 I'm really confused on how to represent the pixels into a vector.
我真的很困惑如何将像素表示为矢量。 So if my image is
H x W
pixels, then my vector should be H*W
dimensional. 因此,如果我的图像是
H x W
像素,那么我的矢量应该是H*W
维度。
What I've tried is : 我试过的是:
int myClass::myFunction(const cv::Mat& img)
{
cv::Mat grayImg;
cvtColor(img, grayImg, CV_RGB2GRAY);
cv::Mat bestLabels, centers, clustered;
cv::Mat p = cv::Mat::zeros(grayImg.cols*grayImg.rows, 1, CV_32F);
int i = -1;
for (int c = 0; c<img.cols; c++) {
for (int r = 0; r < img.rows; r++) {
i++;
p.at<float>(i, 0) = grayImg.at<float>(r, c);
}
}
// I should have obtained the vector in p, so now I want to supply it to k-means:
int K = 2;
cv::kmeans(p, K, bestLabels,
cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0),
3, cv::KMEANS_PP_CENTERS, centers);
// Since K=2, I want to obtain a binary image with this, so the same operation needs to be reversed (grayImg -> p , then bestLabels -> binaryImage)
}
However I'm getting an error : Unhandled exception at 0x00007FFD76406C51 (ntdll.dll) in myapp.exe
但是我收到一个错误:
Unhandled exception at 0x00007FFD76406C51 (ntdll.dll) in myapp.exe
I'm new to OpenCV so I'm not sure how to use any of these functions. 我是OpenCV的新手,所以我不确定如何使用这些功能。 I found this code here .
我在这里找到了这段代码。 For example, why do we use
.at<float>
, some other post says that grayscale image pixels are stored as <char>
s ?? 例如,为什么我们使用
.at<float>
,其他一些帖子说灰度图像像素存储为<char>
s ?? I'm getting confused more and more, so any help would be appreciated :) 我越来越困惑,所以任何帮助将不胜感激:)
Thanks ! 谢谢 !
Thanks to Miki, I found the right way to do it. 感谢Miki,我找到了正确的方法。 But one final question, how do I see the contents of
cv::Mat1b result
? 但最后一个问题,我如何看到
cv::Mat1b result
的内容? I tried printing them like this : 我试着像这样打印它们:
for (int r = 0; r < result.rows; ++r)
{
for (int c = 0; c < result.cols; ++c)
{
result(r, c) = static_cast<uchar>(centers(bestLabels(r*grayImg.cols + c)));
if (result(r, c) != 0) {
std::cout << "result = " << result(r, c) << " \n";
}
}
}
But it keeps printing result=0
, even though I specifically ask it not to :) How do I access the values? 但它保持打印
result=0
,即使我特别要求它不要:)我如何访问值?
You don't need to convert from Mat
to InputArray
, but you can (and should) just pass a Mat
object where an InputArray
is requested. 您不需要从
Mat
转换为InputArray
,但您可以(并且应该)只传递请求InputArray
的Mat
对象。 See here for a detailed explanation 请参阅此处获取详细说明
kmeans accepts an InputArray, that should be an array of N-Dimensional points with float coordinates is needed. kmeans接受一个InputArray,它应该是一个需要浮点坐标的N维点数组。
With Mat
objects, you need img.at<type>(row, col)
to access value of the pixel. 使用
Mat
对象,您需要img.at<type>(row, col)
来访问像素的值。 You can, however, use Mat_
that is a templated version of Mat
where you fix the type, so you can access the value just like img(r,c)
. 但是,您可以使用
Mat_
,它是Mat
的模板化版本,您可以在其中修改类型,因此您可以像img(r,c)
一样访问该值。
So the final code will be: 所以最终的代码是:
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
Mat1b grayImg = imread("path_to_image", IMREAD_GRAYSCALE);
Mat1f data(grayImg.rows*grayImg.cols, 1);
for (int r = 0; r < grayImg.rows; r++)
{
for (int c = 0; c < grayImg.cols; c++)
{
data(r*grayImg.cols + c) = float(grayImg(r, c));
}
}
// Or, equivalently
//Mat1f data;
//grayImg.convertTo(data, CV_32F);
//data = data.reshape(1, 1).t();
// I should have obtained the vector in p, so now I want to supply it to k-means:
int K = 8;
Mat1i bestLabels(data.size(), 0); // integer matrix of labels
Mat1f centers; // float matrix of centers
cv::kmeans(data, K, bestLabels,
cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0),
3, cv::KMEANS_PP_CENTERS, centers);
// Show results
Mat1b result(grayImg.rows, grayImg.cols);
for (int r = 0; r < result.rows; ++r)
{
for (int c = 0; c < result.cols; ++c)
{
result(r, c) = static_cast<uchar>(centers(bestLabels(r*grayImg.cols + c)));
}
}
imshow("Image", grayImg);
imshow("Result", result);
waitKey();
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.