// Extract the descriptor public double[] Apply(Bitmap srcImg) { Fuzzy10Bin Fuzzy10 = new Fuzzy10Bin(false); Fuzzy24Bin Fuzzy24 = new Fuzzy24Bin(false); RGB2HSV HSVConverter = new RGB2HSV(); int[] HSV = new int[3]; double[] Fuzzy10BinResultTable = new double[10]; double[] Fuzzy24BinResultTable = new double[24]; double[] CEDD = new double[144]; int width = srcImg.Width; int height = srcImg.Height; double[,] ImageGrid = new double[width, height]; double[,] PixelCount = new double[2, 2]; int[,] ImageGridRed = new int[width, height]; int[,] ImageGridGreen = new int[width, height]; int[,] ImageGridBlue = new int[width, height]; int NumberOfBlocks = 1600; // blocks int Step_X = (int)Math.Floor(width / Math.Sqrt(NumberOfBlocks)); int Step_Y = (int)Math.Floor(height / Math.Sqrt(NumberOfBlocks)); if ((Step_X % 2) != 0) { Step_X = Step_X - 1; } if ((Step_Y % 2) != 0) { Step_Y = Step_Y - 1; } if (Step_Y < 2) Step_Y = 2; if (Step_X < 2) Step_X = 2; int[] Edges = new int[6]; MaskResults MaskValues; Neighborhood PixelsNeighborhood; PixelFormat fmt = (srcImg.PixelFormat == PixelFormat.Format8bppIndexed) ? PixelFormat.Format8bppIndexed : PixelFormat.Format24bppRgb; for (int i = 0; i < 144; i++) { CEDD[i] = 0; } //**************** //Incase below unsafe code gives error, uncomment the slow GetPixel code and //comment the unsafe code //**************** //for (int y = 0; y < height; y++) //{ // for (int x = 0; x < width; x++) // { // byte red = srcImg.GetPixel(x, y).R; // byte green = srcImg.GetPixel(x, y).G; // byte blue = srcImg.GetPixel(x, y).B; // ImageGrid[x, y] = (0.299f * red + 0.587f * green + 0.114f * red); // ImageGridRed[x, y] = (int)red; // ImageGridGreen[x, y] = (int)green; // ImageGridBlue[x, y] = (int)blue; // } //} BitmapData srcData = srcImg.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, fmt); int offset = srcData.Stride - ((fmt == PixelFormat.Format8bppIndexed) ? width : width * 3); unsafe { byte* src = (byte*)srcData.Scan0.ToPointer(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, src += 3) { ImageGrid[x, y] = (0.299f * src[2] + 0.587f * src[1] + 0.114f * src[0]); ImageGridRed[x, y] = (int)src[2]; ImageGridGreen[x, y] = (int)src[1]; ImageGridBlue[x, y] = (int)src[0]; } src += offset; } } srcImg.UnlockBits(srcData); int[] CororRed = new int[Step_Y * Step_X]; int[] CororGreen = new int[Step_Y * Step_X]; int[] CororBlue = new int[Step_Y * Step_X]; int[] CororRedTemp = new int[Step_Y * Step_X]; int[] CororGreenTemp = new int[Step_Y * Step_X]; int[] CororBlueTemp = new int[Step_Y * Step_X]; int MeanRed , MeanGreen , MeanBlue = 0; int T = -1; int TempSum = 0; double Max = 0; int TemoMAX_X = Step_X * (int)Math.Sqrt(NumberOfBlocks); int TemoMAX_Y = Step_Y * (int)Math.Sqrt(NumberOfBlocks); ; for (int y = 0; y < TemoMAX_Y; y += Step_Y) { for (int x = 0; x < TemoMAX_X; x += Step_X) { MeanRed = 0; MeanGreen = 0; MeanBlue = 0; PixelsNeighborhood.Area1 = 0; PixelsNeighborhood.Area2 = 0; PixelsNeighborhood.Area3 = 0; PixelsNeighborhood.Area4 = 0; Edges[0] = -1; Edges[1] = -1; Edges[2] = -1; Edges[3] = -1; Edges[4] = -1; Edges[5] = -1; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { PixelCount[i, j] = 0; } } TempSum = 0; for (int i = y; i < y + Step_Y; i ++) { for (int j = x; j < x+ Step_X; j ++) { // Color Information CororRed[TempSum] = ImageGridRed[j, i]; CororGreen[TempSum] = ImageGridGreen[j, i]; CororBlue[TempSum] = ImageGridBlue[j, i]; CororRedTemp[TempSum] = ImageGridRed[j, i]; CororGreenTemp[TempSum] = ImageGridGreen[j, i]; CororBlueTemp[TempSum] = ImageGridBlue[j, i]; TempSum++; // Texture Information if (j < (x + Step_X / 2) && i < (y + Step_Y / 2)) PixelsNeighborhood.Area1 += (ImageGrid[j, i]); if (j >= (x + Step_X / 2) && i < (y + Step_Y / 2)) PixelsNeighborhood.Area2 += (ImageGrid[j, i]); if (j < (x + Step_X / 2) && i >= (y + Step_Y / 2)) PixelsNeighborhood.Area3 += (ImageGrid[j, i]); if (j >= (x + Step_X / 2) && i >= (y + Step_Y / 2)) PixelsNeighborhood.Area4 += (ImageGrid[j, i]); } } PixelsNeighborhood.Area1 = (int)(PixelsNeighborhood.Area1 * (4.0 / (Step_X * Step_Y))); PixelsNeighborhood.Area2 = (int)(PixelsNeighborhood.Area2 * (4.0 / (Step_X * Step_Y))); PixelsNeighborhood.Area3 = (int)(PixelsNeighborhood.Area3 * (4.0 / (Step_X * Step_Y))); PixelsNeighborhood.Area4 = (int)(PixelsNeighborhood.Area4 * (4.0 / (Step_X * Step_Y))); MaskValues.Mask1 = Math.Abs(PixelsNeighborhood.Area1 * 2 + PixelsNeighborhood.Area2 * -2 + PixelsNeighborhood.Area3 * -2 + PixelsNeighborhood.Area4 * 2); MaskValues.Mask2 = Math.Abs(PixelsNeighborhood.Area1 * 1 + PixelsNeighborhood.Area2 * 1 + PixelsNeighborhood.Area3 * -1 + PixelsNeighborhood.Area4 * -1); MaskValues.Mask3 = Math.Abs(PixelsNeighborhood.Area1 * 1 + PixelsNeighborhood.Area2 * -1 + PixelsNeighborhood.Area3 * 1 + PixelsNeighborhood.Area4 * -1); MaskValues.Mask4 = Math.Abs(PixelsNeighborhood.Area1 * Math.Sqrt(2) + PixelsNeighborhood.Area2 * 0 + PixelsNeighborhood.Area3 * 0 + PixelsNeighborhood.Area4 * -Math.Sqrt(2)); MaskValues.Mask5 = Math.Abs(PixelsNeighborhood.Area1 * 0 + PixelsNeighborhood.Area2 * Math.Sqrt(2) + PixelsNeighborhood.Area3 * -Math.Sqrt(2) + PixelsNeighborhood.Area4 * 0); Max = Math.Max(MaskValues.Mask1, Math.Max(MaskValues.Mask2, Math.Max(MaskValues.Mask3, Math.Max(MaskValues.Mask4, MaskValues.Mask5)))); MaskValues.Mask1 = MaskValues.Mask1 / Max; MaskValues.Mask2 = MaskValues.Mask2 / Max; MaskValues.Mask3 = MaskValues.Mask3 / Max; MaskValues.Mask4 = MaskValues.Mask4 / Max; MaskValues.Mask5 = MaskValues.Mask5 / Max; T = -1; if (Max < T0) { Edges[0] = 0; T = 0; } else { T = -1; if (MaskValues.Mask1 > T1) { T++; Edges[T] = 1; } if (MaskValues.Mask2 > T2) { T++; Edges[T] = 2; } if (MaskValues.Mask3 > T2) { T++; Edges[T] = 3; } if (MaskValues.Mask4 > T3) { T++; Edges[T] = 4; } if (MaskValues.Mask5 > T3) { T++; Edges[T] = 5; } } for (int i = 0; i < (Step_Y * Step_X); i++) { MeanRed += CororRed[i]; MeanGreen += CororGreen[i]; MeanBlue += CororBlue[i]; } MeanRed = Convert.ToInt32(MeanRed / (Step_Y * Step_X)); MeanGreen = Convert.ToInt32(MeanGreen / (Step_Y * Step_X)); MeanBlue = Convert.ToInt32(MeanBlue / (Step_Y * Step_X)); HSV = HSVConverter.ApplyFilter(MeanRed, MeanGreen, MeanBlue); if (this.Compact == false) { Fuzzy10BinResultTable = Fuzzy10.ApplyFilter(HSV[0], HSV[1], HSV[2], 2); Fuzzy24BinResultTable = Fuzzy24.ApplyFilter(HSV[0], HSV[1], HSV[2], Fuzzy10BinResultTable, 2); for (int i = 0; i <= T; i++) { for (int j = 0; j < 24; j++) { if (Fuzzy24BinResultTable[j] > 0) CEDD[24 * Edges[i] + j] += Fuzzy24BinResultTable[j]; } } } else { Fuzzy10BinResultTable = Fuzzy10.ApplyFilter(HSV[0], HSV[1], HSV[2], 2); for (int i = 0; i <= T; i++) { for (int j = 0; j < 10; j++) { if (Fuzzy10BinResultTable[j] > 0) CEDD[10 * Edges[i] + j] += Fuzzy10BinResultTable[j]; } } } } } double Sum = 0; for (int i = 0; i < 144; i++) { Sum += CEDD[ i]; } for (int i = 0; i < 144; i++) { CEDD[i] = CEDD[i]/Sum; } CEDDQuant Quantization = new CEDDQuant(); CEDD = Quantization.Apply(CEDD); return (CEDD); }
// Extract the descriptor public double[] Apply(Bitmap srcImg) { Fuzzy10Bin Fuzzy10 = new Fuzzy10Bin(false); Fuzzy24Bin Fuzzy24 = new Fuzzy24Bin(false); RGB2HSV HSVConverter = new RGB2HSV(); int[] HSV = new int[3]; double[] Fuzzy10BinResultTable = new double[10]; double[] Fuzzy24BinResultTable = new double[24]; double[] CEDD = new double[144]; int width = srcImg.Width; int height = srcImg.Height; double[,] ImageGrid = new double[width, height]; double[,] PixelCount = new double[2, 2]; int[,] ImageGridRed = new int[width, height]; int[,] ImageGridGreen = new int[width, height]; int[,] ImageGridBlue = new int[width, height]; int NumberOfBlocks = 1600; // blocks int Step_X = (int)Math.Floor(width / Math.Sqrt(NumberOfBlocks)); int Step_Y = (int)Math.Floor(height / Math.Sqrt(NumberOfBlocks)); if ((Step_X % 2) != 0) { Step_X = Step_X - 1; } if ((Step_Y % 2) != 0) { Step_Y = Step_Y - 1; } if (Step_Y < 2) { Step_Y = 2; } if (Step_X < 2) { Step_X = 2; } int[] Edges = new int[6]; MaskResults MaskValues; Neighborhood PixelsNeighborhood; PixelFormat fmt = (srcImg.PixelFormat == PixelFormat.Format8bppIndexed) ? PixelFormat.Format8bppIndexed : PixelFormat.Format24bppRgb; for (int i = 0; i < 144; i++) { CEDD[i] = 0; } //**************** //Incase below unsafe code gives error, uncomment the slow GetPixel code and //comment the unsafe code //**************** //for (int y = 0; y < height; y++) //{ // for (int x = 0; x < width; x++) // { // byte red = srcImg.GetPixel(x, y).R; // byte green = srcImg.GetPixel(x, y).G; // byte blue = srcImg.GetPixel(x, y).B; // ImageGrid[x, y] = (0.299f * red + 0.587f * green + 0.114f * red); // ImageGridRed[x, y] = (int)red; // ImageGridGreen[x, y] = (int)green; // ImageGridBlue[x, y] = (int)blue; // } //} BitmapData srcData = srcImg.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, fmt); int offset = srcData.Stride - ((fmt == PixelFormat.Format8bppIndexed) ? width : width * 3); unsafe { byte *src = (byte *)srcData.Scan0.ToPointer(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, src += 3) { ImageGrid[x, y] = (0.299f * src[2] + 0.587f * src[1] + 0.114f * src[0]); ImageGridRed[x, y] = (int)src[2]; ImageGridGreen[x, y] = (int)src[1]; ImageGridBlue[x, y] = (int)src[0]; } src += offset; } } srcImg.UnlockBits(srcData); int[] CororRed = new int[Step_Y * Step_X]; int[] CororGreen = new int[Step_Y * Step_X]; int[] CororBlue = new int[Step_Y * Step_X]; int[] CororRedTemp = new int[Step_Y * Step_X]; int[] CororGreenTemp = new int[Step_Y * Step_X]; int[] CororBlueTemp = new int[Step_Y * Step_X]; int MeanRed, MeanGreen, MeanBlue = 0; int T = -1; int TempSum = 0; double Max = 0; int TemoMAX_X = Step_X * (int)Math.Sqrt(NumberOfBlocks); int TemoMAX_Y = Step_Y * (int)Math.Sqrt(NumberOfBlocks);; for (int y = 0; y < TemoMAX_Y; y += Step_Y) { for (int x = 0; x < TemoMAX_X; x += Step_X) { MeanRed = 0; MeanGreen = 0; MeanBlue = 0; PixelsNeighborhood.Area1 = 0; PixelsNeighborhood.Area2 = 0; PixelsNeighborhood.Area3 = 0; PixelsNeighborhood.Area4 = 0; Edges[0] = -1; Edges[1] = -1; Edges[2] = -1; Edges[3] = -1; Edges[4] = -1; Edges[5] = -1; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { PixelCount[i, j] = 0; } } TempSum = 0; for (int i = y; i < y + Step_Y; i++) { for (int j = x; j < x + Step_X; j++) { // Color Information CororRed[TempSum] = ImageGridRed[j, i]; CororGreen[TempSum] = ImageGridGreen[j, i]; CororBlue[TempSum] = ImageGridBlue[j, i]; CororRedTemp[TempSum] = ImageGridRed[j, i]; CororGreenTemp[TempSum] = ImageGridGreen[j, i]; CororBlueTemp[TempSum] = ImageGridBlue[j, i]; TempSum++; // Texture Information if (j < (x + Step_X / 2) && i < (y + Step_Y / 2)) { PixelsNeighborhood.Area1 += (ImageGrid[j, i]); } if (j >= (x + Step_X / 2) && i < (y + Step_Y / 2)) { PixelsNeighborhood.Area2 += (ImageGrid[j, i]); } if (j < (x + Step_X / 2) && i >= (y + Step_Y / 2)) { PixelsNeighborhood.Area3 += (ImageGrid[j, i]); } if (j >= (x + Step_X / 2) && i >= (y + Step_Y / 2)) { PixelsNeighborhood.Area4 += (ImageGrid[j, i]); } } } PixelsNeighborhood.Area1 = (int)(PixelsNeighborhood.Area1 * (4.0 / (Step_X * Step_Y))); PixelsNeighborhood.Area2 = (int)(PixelsNeighborhood.Area2 * (4.0 / (Step_X * Step_Y))); PixelsNeighborhood.Area3 = (int)(PixelsNeighborhood.Area3 * (4.0 / (Step_X * Step_Y))); PixelsNeighborhood.Area4 = (int)(PixelsNeighborhood.Area4 * (4.0 / (Step_X * Step_Y))); MaskValues.Mask1 = Math.Abs(PixelsNeighborhood.Area1 * 2 + PixelsNeighborhood.Area2 * -2 + PixelsNeighborhood.Area3 * -2 + PixelsNeighborhood.Area4 * 2); MaskValues.Mask2 = Math.Abs(PixelsNeighborhood.Area1 * 1 + PixelsNeighborhood.Area2 * 1 + PixelsNeighborhood.Area3 * -1 + PixelsNeighborhood.Area4 * -1); MaskValues.Mask3 = Math.Abs(PixelsNeighborhood.Area1 * 1 + PixelsNeighborhood.Area2 * -1 + PixelsNeighborhood.Area3 * 1 + PixelsNeighborhood.Area4 * -1); MaskValues.Mask4 = Math.Abs(PixelsNeighborhood.Area1 * Math.Sqrt(2) + PixelsNeighborhood.Area2 * 0 + PixelsNeighborhood.Area3 * 0 + PixelsNeighborhood.Area4 * -Math.Sqrt(2)); MaskValues.Mask5 = Math.Abs(PixelsNeighborhood.Area1 * 0 + PixelsNeighborhood.Area2 * Math.Sqrt(2) + PixelsNeighborhood.Area3 * -Math.Sqrt(2) + PixelsNeighborhood.Area4 * 0); Max = Math.Max(MaskValues.Mask1, Math.Max(MaskValues.Mask2, Math.Max(MaskValues.Mask3, Math.Max(MaskValues.Mask4, MaskValues.Mask5)))); MaskValues.Mask1 = MaskValues.Mask1 / Max; MaskValues.Mask2 = MaskValues.Mask2 / Max; MaskValues.Mask3 = MaskValues.Mask3 / Max; MaskValues.Mask4 = MaskValues.Mask4 / Max; MaskValues.Mask5 = MaskValues.Mask5 / Max; T = -1; if (Max < T0) { Edges[0] = 0; T = 0; } else { T = -1; if (MaskValues.Mask1 > T1) { T++; Edges[T] = 1; } if (MaskValues.Mask2 > T2) { T++; Edges[T] = 2; } if (MaskValues.Mask3 > T2) { T++; Edges[T] = 3; } if (MaskValues.Mask4 > T3) { T++; Edges[T] = 4; } if (MaskValues.Mask5 > T3) { T++; Edges[T] = 5; } } for (int i = 0; i < (Step_Y * Step_X); i++) { MeanRed += CororRed[i]; MeanGreen += CororGreen[i]; MeanBlue += CororBlue[i]; } MeanRed = Convert.ToInt32(MeanRed / (Step_Y * Step_X)); MeanGreen = Convert.ToInt32(MeanGreen / (Step_Y * Step_X)); MeanBlue = Convert.ToInt32(MeanBlue / (Step_Y * Step_X)); HSV = HSVConverter.ApplyFilter(MeanRed, MeanGreen, MeanBlue); if (this.Compact == false) { Fuzzy10BinResultTable = Fuzzy10.ApplyFilter(HSV[0], HSV[1], HSV[2], 2); Fuzzy24BinResultTable = Fuzzy24.ApplyFilter(HSV[0], HSV[1], HSV[2], Fuzzy10BinResultTable, 2); for (int i = 0; i <= T; i++) { for (int j = 0; j < 24; j++) { if (Fuzzy24BinResultTable[j] > 0) { CEDD[24 * Edges[i] + j] += Fuzzy24BinResultTable[j]; } } } } else { Fuzzy10BinResultTable = Fuzzy10.ApplyFilter(HSV[0], HSV[1], HSV[2], 2); for (int i = 0; i <= T; i++) { for (int j = 0; j < 10; j++) { if (Fuzzy10BinResultTable[j] > 0) { CEDD[10 * Edges[i] + j] += Fuzzy10BinResultTable[j]; } } } } } } double Sum = 0; for (int i = 0; i < 144; i++) { Sum += CEDD[i]; } for (int i = 0; i < 144; i++) { CEDD[i] = CEDD[i] / Sum; } CEDDQuant Quantization = new CEDDQuant(); CEDD = Quantization.Apply(CEDD); return(CEDD); }