Stopwatch sw = new Stopwatch();OpenCV版本(使用EmguCV对OpenCV的PInvoke封装)
sw.Start();
ImageLab24 imgLab = null;
imgLab = new ImageLab24(img); // img 是一个 ImageRgb24 对象
sw.Stop();
Message = sw.ElapsedMilliseconds.ToString();
private Image TestOpenCV()下面针对三副不同大小的图像进行测试,每张图像测试4次,每次测试将上面两种实现各跑一次,前2次,先跑OpenCV/PInvoke实现,后2次,先跑C#实现,单位皆为ms。
{
Image imgBgr = new Image(imgMain.Image as Bitmap);
Image imgLab = new Image(new Size(imgBgr.Width, imgBgr.Height));
Stopwatch sw = new Stopwatch();
sw.Start();
CvInvoke.cvCvtColor(imgBgr.Ptr,imgLab.Ptr, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_BGR2Lab);
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString() + "ms");
return imgLab;
}
图像1,大小:485×342从测试结果可以看出,C# 和 OpenCV/PInvoke的性能极为接近。
A: 5 3 5 3
B: 41 5 6 2
图像2,大小:1845×611
A:25 23 23 23
B:23 34 20 21
图像3,大小:3888×2592
A:209 210 211 210
B:185 188 191 185
Lab24[] ColorMap首先初始化ColorMap:
ColorMap = new Lab24[4096];下面测试(C)查表计算的性能,结果和(A)C#实现与(B)C实现放在一起做对比。
for (int r = 0; r < 16; r++)
{
for (int g = 0; g < 16; g++)
{
for (int b = 0; b < 16; b++)
{
Rgb24 rgb = new Rgb24(r * 16, g * 16, b * 16);
Lab24 lab = Lab24.CreateFrom(rgb);
ColorMap[(r 4) > 4) > 4) ];
rgbStart++;
labStart++;
}
return lab;
}
图像1,大小:485×3425. 原地进行变换
A: 5 3 5 3
B: 41 5 6 2
C: 3 2 2 2
图像2,大小:1845×611
A:25 23 23 23
B:23 34 20 21
C: 15 15 15 15
图像3,大小:3888×2592
A:209 210 211 210
B:185 188 191 185
C: 136 134 135 135
Rgb24[] ColorMapInSpace下面测试D(原地查表变换)的性能,结果和(A)C#实现、(B)C实现、(C)查表计算进行比较:
...
ColorMap = new Lab24[4096];
ColorMapInSpace = new Rgb24[4096];
for (int r = 0; r < 16; r++)
{
for (int g = 0; g < 16; g++)
{
for (int b = 0; b < 16; b++)
{
Rgb24 rgb = new Rgb24(r * 16, g * 16, b * 16);
Lab24 lab = Lab24.CreateFrom(rgb);
ColorMap[(r 4)];
rgbStart++;
}
}
图像1,大小:485×3426. 为什么用C#而不是C/C++
A: 5 3 5 3
B: 41 5 6 2
C: 3 2 2 2
D: 2 1 2 1
图像2,大小:1845×611
A:25 23 23 23
B:23 34 20 21
C: 15 15 15 15
D: 13 13 13 13
图像3,大小:3888×2592
A:209 210 211 210
B:185 188 191 185
C: 136 134 135 135
D: 117 118 122 117
voidF: 查表实现
::ImageQualityDetector::ConvertToLab(Orc::ImageInfo &img)
{
static unsigned short icvLabCubeRootTab[] = {
0,161,203…… };
const float labXr_32f = 0.433953f /* = xyzXr_32f / 0.950456 */;
const float labXg_32f = 0.376219f /* = xyzXg_32f / 0.950456 */;
const float labXb_32f = 0.189828f /* = xyzXb_32f / 0.950456 */;
const float labYr_32f = 0.212671f /* = xyzYr_32f */;
const float labYg_32f = 0.715160f /* = xyzYg_32f */;
const float labYb_32f = 0.072169f /* = xyzYb_32f */;
const float labZr_32f = 0.017758f /* = xyzZr_32f / 1.088754 */;
const float labZg_32f = 0.109477f /* = xyzZg_32f / 1.088754 */;
const float labZb_32f = 0.872766f /* = xyzZb_32f / 1.088754 */;
const float labRx_32f = 3.0799327f /* = xyzRx_32f * 0.950456 */;
const float labRy_32f = (-1.53715f) /* = xyzRy_32f */;
const float labRz_32f = (-0.542782f)/* = xyzRz_32f * 1.088754 */;
const float labGx_32f = (-0.921235f)/* = xyzGx_32f * 0.950456 */;
const float labGy_32f = 1.875991f /* = xyzGy_32f */ ;
const float labGz_32f = 0.04524426f /* = xyzGz_32f * 1.088754 */;
const float labBx_32f = 0.0528909755f /* = xyzBx_32f * 0.950456 */;
const float labBy_32f = (-0.204043f) /* = xyzBy_32f */;
const float labBz_32f = 1.15115158f /* = xyzBz_32f * 1.088754 */;
const float labT_32f = 0.008856f;
const int lab_shift = 10;
const float labLScale2_32f = 903.3f;
const int labXr = (int)((labXr_32f) * (1 4) > 4)) ;
line[0] = (byte)l;
line[1] = (byte)a;
line[2] = (byte)b;
line += nChannel;
}
}
}
void测试结果:
::ImageQualityDetector::FastConvertToLab(Orc::ImageInfo &img)
{
static const byte Rgb2LabSmallTable[] = {
0, 129, 128 ……
};
int width = img.Width;
int height = img.Height;
int nChannel = img.NChannel;
int redChannel = img.RedChannel;
int greenChannel = img.GreenChannel;
int blueChannel = img.BlueChannel;
for(int h = 0; h < height; h++)
{
byte *line = img.GetLine(h);
for(int w = 0; w < width; w++)
{
int red = line[redChannel];
int green = line[greenChannel];
int blue = line[blueChannel];
int index = 3 * (((red >> 4) > 4) > 4)) ;
line[0] = Rgb2LabSmallTable[index];
line[1] = Rgb2LabSmallTable[index + 1];
line[2] = Rgb2LabSmallTable[index + 2];
line += nChannel;
}
}
}
图像2,大小:1845×611====
A:25 23 23 23
B:23 34 20 21
C: 15 15 15 15
D: 13 13 13 13
E: 32 30 37 37
F: 15 10 13 11
图像3,大小:3888×2592
A:209 210 211 210
B:185 188 191 185
C: 136 134 135 135
D: 117 118 122 117
E: 242 240 243 239
F: 70 69 67 67
static byte[] Rgb2LabSmallTable = new byte[] {测试结果:
0, 129, 128, … }
private unsafe void ConvertToImageLab24Fast(ImageRgb24 img)
{
Rgb24* rgbStart = img.Start;
Rgb24* rgbEnd = img.Start + img.Length;
while (rgbStart != rgbEnd)
{
Rgb24 rgb = *rgbStart;
int index = (((int)(rgb.Red) >> 4) > 4) > 4);
rgbStart->Red = Rgb2LabSmallTable[index];
rgbStart->Green = Rgb2LabSmallTable[index+1];
rgbStart->Blue = Rgb2LabSmallTable[index+2];
rgbStart++;
}
}
图像2,大小:1845×611====
A:25 23 23 23
B:23 34 20 21
C: 15 15 15 15
D: 13 13 13 13
E: 32 30 37 37
F: 15 10 13 11
G: 12 11 13 11
图像3,大小:3888×2592
A:209 210 211 210
B:185 188 191 185
C: 136 134 135 135
D: 117 118 122 117
E: 242 240 243 239
F: 70 69 67 67
G: 64 64 65 64
图像2,大小:1845×611结论:
H: 31 29 36 32
I: 10 10 10 10
J: 39 33 33 30
K: 9 8 8 8
图像3,大小:3888×2592
H: 195 194 194 195
I: 53 52 51 52
J: 220 218 218 222
K: 41 42 41 41
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |