/* The Visual C# 2010 code for Multi-Texton Histogram. For more information, refer to: Guang-Hai Liu, Lei Zhang,etc. Image Retrieval Based on Multi-Texton Histogram. Pattern Recognition,2010, 43(7):2380-2389. Copyright (C) 2010 Guang-Hai Liu ; Lei Zhang Note: The MTH algorithm is patented in china and cannot be used in commercial products without permission from the authors (Guang-Hai Liu and Lei Zhang). @version 1.1.2-20100820 */ -------------------------------------------------------------------------------- System.Drawing.Bitmap curBitmap; string curFileName; curFileName = textBox6.Text + "\\" + Num.ToString() + ".jpg"; curBitmap = new Bitmap(curFileName); int Width = curBitmap.Width; int Height = curBitmap.Height; int CSA=64; int CSB=18; int[, ,] RGB = new int[3, Width, Height]; double[,] theta = new double[Width, Height]; //---------------Get Pixels Value----------------------- for (int i = 1; i <= wid - 2; i++) { for (int j = 1; j <= hei - 2; j++) { Color curColor; curColor = curBitmap.GetPixel(i, j); RGB[0, i, j] = (int)curColor.R; RGB[1, i, j] = (int)curColor.G; RGB[2, i, j] = (int)curColor.B; } } curBitmap.Dispose(); //---------------Texture Orientation Detection----------------------- int[,] Ori = new int[wid, hei]; double gxx = 0.0, gyy = 0.0, gxy = 0.0; double rh = 0.0, gh = 0.0, bh = 0.0; double rv = 0.0, gv = 0.0, bv = 0.0; double theta = 0.0; for (int i = 1; i <= Width - 2; i++) { for (int j = 1; j <= Height - 2; j++) { rh = (double)(RGB[0, i - 1, j + 1] + 2 * RGB[0, i, j + 1] + RGB[0, i + 1, j + 1]) - (RGB[0, i - 1, j - 1] + 2 * RGB[0, i, j - 1] + RGB[0, i + 1, j - 1]); gh = (double)(RGB[1, i - 1, j + 1] + 2 * RGB[1, i, j + 1] + RGB[1, i + 1, j + 1]) - (RGB[1, i - 1, j - 1] + 2 * RGB[1, i, j - 1] + RGB[1, i + 1, j - 1]); bh = (double)(RGB[2, i - 1, j + 1] + 2 * RGB[2, i, j + 1] + RGB[2, i + 1, j + 1]) - (RGB[2, i - 1, j - 1] + 2 * RGB[2, i, j - 1] + RGB[2, i + 1, j - 1]); rv = (double)(RGB[0, i + 1, j - 1] + 2 * RGB[0, i + 1, j] + RGB[0, i + 1, j + 1]) - (RGB[0, i - 1, j - 1] + 2 * RGB[0, i - 1, j] + RGB[0, i - 1, j + 1]); gv = (double)(RGB[1, i + 1, j - 1] + 2 * RGB[1, i + 1, j] + RGB[1, i + 1, j + 1]) - (RGB[1, i - 1, j - 1] + 2 * RGB[1, i - 1, j] + RGB[1, i - 1, j + 1]); bv = (double)(RGB[2, i + 1, j - 1] + 2 * RGB[2, i + 1, j] + RGB[2, i + 1, j + 1]) - (RGB[2, i - 1, j - 1] + 2 * RGB[2, i - 1, j] + RGB[2, i - 1, j + 1]); gxx = Math.Sqrt(rh * rh + gh * gh + bh * bh); gyy = Math.Sqrt(rv * rv + gv * gv + bv * bv); gxy = rh * rv + gh * gv + bh * bv; theta[i,j] = (Math.Acos(gxy / (gxx * gyy + 0.0001)) * 180 /Math.PI); } } int[,] ImageX = new int[Width, Height]; int R=0, G=0 , B=0; int SI=0 , VI=0 , HI=0 ; //------------------Color Quantization in RGB Color Space-------------------- for (int i=0;i<=Width-1;i++) { for (int j=0;j<=Height-1;j++) { R = (int)rValues[i, j]; G = (int)gValues[i, j]; B = (int)bValues[i, j]; if (R >=0 && R <= 64) VI = 0; if (R >= 65 && R <= 128) VI = 1; if (R >= 129 && R <= 192) VI = 2; if (R >= 193 && R <= 255) VI = 3; //------------------------------------- if (G>= 0 && G <= 64) SI = 0; if (G >= 65 && G <= 128) SI = 1; if (G >= 129 && G <= 192) SI = 2; if (G >= 193 && G <= 255) SI = 3; // ------------------------------------------- if (B >= 0 && B <= 64) HI = 0; if (B >= 65 && B <= 128) HI = 1; if (B >= 129 && B <= 192) HI = 2; if (B >= 193 && B <= 255) HI = 3; //------------------------------------------- ImageX[i, j] = 16 * VI + 4 * SI + HI; } } //-----------------quantize texture Orientation uniformly into 18 orientations with 10 as the step-length---------------------- double[,] Ori = new double[Width, Height]; for (int i=0;i<=Width-1;i++) { for (int j=0;j<=Height-1;j++) { Ori[i,j]=Math.Round(theta[i,j]*CSB/180); if (Ori[i,j]>=CSB-1) Ori[i,j]=CSB-1; } } //--------------Texton Detection---------------------- int[,] Texton = new int[Width, Height]; for (int i=0;i<=(Width/2-1);i++) { for (int j=0;j<=(Height/2)-1;j++) { //----------------------------------------- if (ImageX[2*i,2*j]==ImageX[2*i+1,2*j+1]) { Texton[2 * i, 2 * j] = ImageX[2 * i, 2 * j]; Texton[2 * i + 1, 2 * j] = ImageX[2 * i + 1, 2 * j]; Texton[2 * i, 2 * j + 1] = ImageX[2 * i, 2 * j + 1]; Texton[2 * i + 1, 2 * j + 1] = ImageX[2 * i + 1, 2 * j + 1]; } //------------------------------------ if (ImageX[2*i,2*j+1]==ImageX[2*i+1,2*j]) { Texton[2 * i, 2 * j] = ImageX[2 * i, 2 * j]; Texton[2 * i + 1, 2 * j] = ImageX[2 * i + 1, 2 * j]; Texton[2 * i, 2 * j + 1] = ImageX[2 * i, 2 * j + 1]; Texton[2 * i + 1, 2 * j + 1] = ImageX[2 * i + 1, 2 * j + 1]; } //--------------------------------------- if (ImageX[2*i,2*j]==ImageX[2*i+1,2*j]) { Texton[2 * i, 2 * j] = ImageX[2 * i, 2 * j]; Texton[2 * i + 1, 2 * j] = ImageX[2 * i + 1, 2 * j]; Texton[2 * i, 2 * j + 1] = ImageX[2 * i, 2 * j + 1]; Texton[2 * i + 1, 2 * j + 1] = ImageX[2 * i + 1, 2 * j + 1]; } //----------------------------------------- if (ImageX[2*i,2*j]==ImageX[2*i,2*j+1]) { Texton[2 * i, 2 * j] = ImageX[2 * i, 2 * j]; Texton[2 * i + 1, 2 * j] = ImageX[2 * i + 1, 2 * j]; Texton[2 * i, 2 * j + 1] = ImageX[2 * i, 2 * j + 1]; Texton[2 * i + 1, 2 * j + 1] = ImageX[2 * i + 1, 2 * j + 1]; } //----------------------------------------- } } //-----------------------------------Multi-Texton Histogram----------------------------------------- int[] MatrixH = new int[CSA+CSB]; int[] MatrixV = new int[CSA+CSB]; int[] MatrixRD = new int[CSA+CSB]; int[] MatrixLD = new int[CSA+CSB]; int D = 1; // distance parameter กก for (int i = 0; i <= Width - 1; i++) { for (int j = 0; j <= Height - D - 1; j++) { if (Ori[i, j + D] == Ori[i, j]) MatrixH[Texton[i, j]] += 1; if (Texton[i, j + D] == Texton[i, j]) MatrixH[CSA + Ori[i, j]] += 1; } } for (int i = 0; i <= Width - D - 1; i++) { for (int j = 0; j <= Height - 1; j++) { if (Ori[i + D, j] == Ori[i, j]) MatrixV[Texton[i, j]] += 1; if (Texton[i + D, j] == Texton[i, j]) MatrixV[CSA + Ori[i, j]] += 1; } } for (int i = 0; i <= Width - D - 1; i++) { for (int j = 0; j <= Height - D - 1; j++) { if (Ori[i + D, j + D] == Ori[i, j]) MatrixRD[Texton[i, j]] += 1; if (Texton[i + D, j + D] == Texton[i, j]) MatrixRD[CSA + Ori[i, j]] += 1; } } for (int i = D; i <= Width - 1; i++) { for (int j = 0; j <= Height - D - 1; j++) { if (Ori[i - D, j + D] == Ori[i, j]) MatrixLD[Texton[i, j]] += 1; if (Texton[i - D, j + D] == Texton[i, j]) MatrixLD[CSA + Ori[i, j]] += 1; } } //-------------------Features vectors-------------------------------------------------- double[] MTH = new double[CSA+CSB]; for (int i=0;i<=CSA+CSB-1;i++) { MTH[i]=(MatrixH[i]+MatrixV[i]+MatrixRD[i]+MatrixLD[i])/4.0; }