我需要以最快的方式迭代EmguCV位图矩阵并设置像素。我在google之后发现了这个,但700x500图像需要大约3秒钟:
文件说访问(获取)数据矩阵只是o(1)但它没有明确声明设置数据。
for(int i = 0; i < img.Rows ; i++)
for(int j = 0; j < img.Cols; j++){
img.Data[x,y,0] = 255;
img.Data[x,y,1] = 255;
img.Data[x,y,2] = 255;
}
提前致谢。
答案 0 :(得分:3)
Emgu.CV.Image<>
的{{1}}属性的getter返回对类内部使用的三维数组的引用。当您分配给该数组的元素时(正如您在上面的代码中所做的那样),您没有调用Data
属性的setter,而是在操作数组本身。
我怀疑您遇到的速度减慢与调用非托管代码有关,因为EmguCV代码基本上不受管理。
试试这个并查看速度是否有任何变化:
Data
Byte[,,] data = img.Data;
int rows = img.Rows;
int cols = img.Cols;
for (int y = 0; y < rows; ++i)
{
for (int x = 0; x < cols; ++x)
{
data[x, y, 0] = 255;
data[x, y, 1] = 255;
data[x, y, 2] = 255;
}
}
类还有一个方法Image
,可以将每个像素设置为特定值。如果您要实现的目的是将图像清除为白色,请尝试调用SetValue
(或者您正在使用的图像颜色类型),而不是手动执行。可能会更快。
答案 1 :(得分:1)
for (int y = 0; y < rows; y++)
{
for (int x = 0; x < cols; x++)
{
b = (int)frameClone.Data[y, x, 0];
g = (int)frameClone.Data[y, x, 1];
r = (int)frameClone.Data[y, x, 2];
}
currIntensity = b + g + r;
}
答案 2 :(得分:1)
将Emgu.Cv.Image
转换为System.Drawing.Bitmap
并使用安全或不安全的方法迭代位图要快得多。
安全方法使用
color.toargb = bmp.getpixel(X, Y).toargb / bmp.setpixel(X, Y).toargb
并且相当直接。
bmp.lockbits(bmp_data)
和interopservices.marshal
将bmp数据复制到数组。你可以在网上找到大量的例子。我对EmguCV 3.0像素访问感到非常失望。
答案 3 :(得分:0)
这是我用来替换颜色的方法,它将给定的不在给定(差异)范围内的任何颜色替换为所需的颜色。它非常快,使用不安全
/// <summary>
/// Replaces a given color in a bitmap
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
public static unsafe void ReplaceColor(Bitmap image,
Color FindColor,
int WithinDistance,
Color ReplaceColor
)
{
byte FindColorR = (byte)FindColor.R;
byte FindColorG = (byte)FindColor.G;
byte FindColorB = (byte)FindColor.B;
byte ReplaceColorR = (byte)ReplaceColor.R;
byte ReplaceColorG = (byte)ReplaceColor.G;
byte ReplaceColorB = (byte)ReplaceColor.B;
byte WithinDistanceByte = (byte)WithinDistance;
BitmapData imageData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
int bytesPerPixel = 3;
byte* scan0 = (byte*)imageData.Scan0.ToPointer();
int stride = imageData.Stride;
PixelData NewData = new PixelData(image.Height,image.Size);
for (int y = 0; y < imageData.Height; y++)
{
byte* row = scan0 + (y * stride);
for (int x = 0; x < imageData.Width; x++)
{
int bIndex = x * bytesPerPixel;
int gIndex = bIndex + 1;
int rIndex = bIndex + 2;
byte pixelR = row[rIndex];
byte pixelG = row[gIndex];
byte pixelB = row[bIndex];
if( Math.Abs(FindColorR - pixelR) > WithinDistanceByte &&
Math.Abs(FindColorG - pixelG) > WithinDistanceByte &&
Math.Abs(FindColorB - pixelB) > WithinDistanceByte )
{
row[rIndex] = ReplaceColorR;
row[gIndex] = ReplaceColorG;
row[bIndex] = ReplaceColorB;
}
else
{
row[rIndex] = FindColorR;
row[gIndex] = FindColorG;
row[bIndex] = FindColorB;
}
}
}
image.UnlockBits(imageData);
}