gpt4 book ai didi

c# - 在 EmguCV 中使用 cvKMeans2 的异常

转载 作者:太空宇宙 更新时间:2023-11-03 21:22:42 25 4
gpt4 key购买 nike

我正在尝试转换 this snippet of code在使用 C# 的 Emgu CV 中。我认为我将大部分内容转换为它们在 EmguCV 中应该是的内容,但 cvKMeans2 一直向我射击没有意义的异常。

这是我的代码:

Image<Bgr, float> src = new Image<Bgr, float>("c:\\blanc.jpg");
Matrix<Single> samples = new Matrix<Single>(src.Rows * src.Cols, 3);
for (int y = 0; y < src.Rows; y++)
{
for (int x = 0; x < src.Cols; x++)
{
for( int z = 0; z < 3; z++)
{
if(z == 0)
samples[y + x * src.Rows, z] = Convert.ToSingle(src[y, x].Blue);
else if(z == 1)
samples[y + x * src.Rows, z] = Convert.ToSingle(src[y, x].Green);
else if (z == 2)
samples[y + x * src.Rows, z] = Convert.ToSingle(src[y, x].Red);
}
}
}

MCvTermCriteria term = new MCvTermCriteria(10000, 0.0001);
term.type = TERMCRIT.CV_TERMCRIT_ITER | TERMCRIT.CV_TERMCRIT_EPS;

int clusterCount = 3;
Matrix<Int32> labels = new Matrix<Int32>(src.Width, 1);
int attempts = 5;
Matrix<Single> centers = new Matrix<Single>(clusterCount, samples.Cols);
CvInvoke.cvKMeans2(samples, clusterCount, labels, term, attempts, IntPtr.Zero, KMeansInitType.PPCenters, centers, IntPtr.Zero );

Image<Bgr, float> new_image = new Image<Bgr, float>(src.Size);

for (int y = 0; y < src.Rows; y++)
{
for (int x = 0; x < src.Cols; x++)
{
//nTotal++;
int cluster_idx = labels[y + x * src.Rows, 0];

float n1 = centers[cluster_idx, 0];
float n2 = centers[cluster_idx, 1];
float n3 = centers[cluster_idx, 2];

MCvScalar sca = new MCvScalar(n1, n2, n3);
CvInvoke.cvSet2D(new_image, y, x, sca);
}
}

CvInvoke.cvShowImage( "clustered image", new_image );
CvInvoke.cvWaitKey( 0 );

我一直收到这个异常:

Additional information: OpenCV: labels.isContinuous() && labels.type() == CV_32S && (labels.cols == 1 || labels.rows == 1) && labels.cols + labels.rows - 1 == data.rows

标签必须是 Single 类型是没有意义的,因为我需要在 cvKMeans2 之后将它用作循环中的索引。任何人都可以帮我让这段代码工作吗?如果此代码有效,我们很有可能会购买 Emgu 的商业许可证以在我们的软件中使用。

谢谢!

编辑

根据下面的答案,我修改了我的代码并让它像这样工作:

Image<Bgr, float> src = new Image<Bgr, float>(@"C:\\test.png");
Matrix<float> samples = new Matrix<float>(src.Rows * src.Cols, 1, 3);
Matrix<int> finalClusters = new Matrix<int>(src.Rows * src.Cols, 1);

for (int y = 0; y < src.Rows; y++)
{
for (int x = 0; x < src.Cols; x++)
{
samples.Data[y + x * src.Rows, 0] = (float)src[y, x].Blue;
samples.Data[y + x * src.Rows, 1] = (float)src[y, x].Green;
samples.Data[y + x * src.Rows, 2] = (float)src[y, x].Red;
}
}

MCvTermCriteria term = new MCvTermCriteria(10000, 0.0001);
term.type = TERMCRIT.CV_TERMCRIT_ITER | TERMCRIT.CV_TERMCRIT_EPS;

int clusterCount = 3;
int attempts = 5;
Matrix<Single> centers = new Matrix<Single>(clusterCount, samples.Cols, 3);
CvInvoke.cvKMeans2(samples, clusterCount, finalClusters, term, attempts, IntPtr.Zero, KMeansInitType.PPCenters, centers, IntPtr.Zero);

Image<Bgr, Byte> new_image = new Image<Bgr, Byte>(src.Size);

for (int y = 0; y < src.Rows; y++)
{
for (int x = 0; x < src.Cols; x++)
{
int cluster_idx = finalClusters[y + x * src.Rows, 0];
MCvScalar sca1 = CvInvoke.cvGet2D(centers, cluster_idx, 0);
Bgr color = new Bgr(sca1.v0, sca1.v1, sca1.v2);

PointF p = new PointF(x, y);
new_image.Draw(new CircleF(p, 1.0f), color, 1);
}
}

CvInvoke.cvShowImage("clustered image", new_image);
CvInvoke.cvWaitKey(0);

最佳答案

我看一下 example you refers to并且我编写了一些适用于在 rgb 空间中执行 kmeans 的输入 rgb 图像的普通代码。您可以调整一些参数以使其适应您的需要。

以这张输入图像为例: INPUT IMAGE

EMGUCV 代码

Bgr[] clusterColors = new Bgr[] {
new Bgr(0,0,255),
new Bgr(0, 255, 0),
new Bgr(255, 100, 100),
new Bgr(255,0,255),
new Bgr(133,0,99),
new Bgr(130,12,49),
new Bgr(0, 255, 255)};

Image<Bgr, float> src = new Image<Bgr, float>("fotobp.jpg");
Matrix<float> samples = new Matrix<float>(src.Rows * src.Cols, 1, 3);
Matrix<int> finalClusters = new Matrix<int>(src.Rows * src.Cols, 1);

for (int y = 0; y < src.Rows; y++)
{
for (int x = 0; x < src.Cols; x++)
{
samples.Data[y + x * src.Rows, 0] = (float)src[y, x].Blue;
samples.Data[y + x * src.Rows, 1] = (float)src[y, x].Green;
samples.Data[y + x * src.Rows, 2] = (float)src[y, x].Red;
}
}

MCvTermCriteria term = new MCvTermCriteria(100, 0.5);
term.type = TERMCRIT.CV_TERMCRIT_ITER | TERMCRIT.CV_TERMCRIT_EPS;

int clusterCount = 4;
int attempts = 5;
Matrix<Single> centers = new Matrix<Single>(clusterCount, src.Rows * src.Cols);
CvInvoke.cvKMeans2(samples, clusterCount, finalClusters, term, attempts, IntPtr.Zero, KMeansInitType.PPCenters, IntPtr.Zero, IntPtr.Zero);

Image<Bgr, float> new_image = new Image<Bgr, float>(src.Size);

for (int y = 0; y < src.Rows; y++)
{
for (int x = 0; x < src.Cols; x++)
{
PointF p = new PointF(x, y);
new_image.Draw(new CircleF(p, 1.0f), clusterColors[finalClusters[y + x * src.Rows, 0]], 1);
}
}

CvInvoke.cvShowImage("clustered image", new_image);
CvInvoke.cvWaitKey(0);

结果(CLUSTER_NUM = 4) enter image description here

关于c# - 在 EmguCV 中使用 cvKMeans2 的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14944253/

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