Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Emgu.CV.Structure;
- using Emgu.CV;
- using System.Diagnostics;
- using System.Linq;
- namespace SS_OpenCV
- {
- class ImageClass
- {
- static public void ConvertToGray(Image<Bgr, byte> img)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = widthStep - nChan * width;
- int x, y;
- byte gray;
- if (nChan == 3) // image in RGB
- {
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- gray = (byte)Math.Round((dataPtr[0] + dataPtr[1] + dataPtr[2]) / 3.0);
- dataPtr[0] = gray;
- dataPtr[1] = gray;
- dataPtr[2] = gray;
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Convert to Gray
- // *** Required SS Operations ***
- public static void Negative(Image<Bgr, byte> img)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- int width = img.Width;
- int height = img.Height;
- int widthStep = m.widthStep;
- int nChan = m.nChannels; // number of channels - 3
- int padding = widthStep - nChan * width;
- int x, y;
- if (nChan == 3) // image in RGB
- {
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- dataPtr[0] = (byte)(255 - dataPtr[0]);
- dataPtr[1] = (byte)(255 - dataPtr[1]);
- dataPtr[2] = (byte)(255 - dataPtr[2]);
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Negative
- public static void BrightContrast(Image<Bgr, byte> img, int bright, double contrast)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = widthStep - nChan * width;
- int x, y;
- int b, r, g;
- if (nChan == 3) // image in RGB
- {
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- b = (int)Math.Round(dataPtr[0] * contrast + bright);
- if (b > 255)
- dataPtr[0] = (byte)255;
- else if (b < 0)
- dataPtr[0] = (byte)0;
- else
- dataPtr[0] = (byte)b;
- g = (int)Math.Round(dataPtr[1] * contrast + bright);
- if (g > 255)
- dataPtr[1] = (byte)255;
- else if (g < 0)
- dataPtr[1] = (byte)0;
- else
- dataPtr[1] = (byte)g;
- r = (int)Math.Round(dataPtr[2] * contrast + bright);
- if (r > 255)
- dataPtr[2] = (byte)255;
- else if (r < 0)
- dataPtr[2] = (byte)0;
- else
- dataPtr[2] = (byte)r;
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Bright Contrast
- public static void RedChannel(Image<Bgr, byte> img)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = widthStep - nChan * width;
- int x, y;
- if (nChan == 3) // image in RGB
- {
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- dataPtr[0] = (byte)dataPtr[2];
- dataPtr[1] = (byte)dataPtr[2];
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Red Channel
- public static void Translation(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, int dx, int dy)
- {
- unsafe
- {
- MIplImage m = imgCopy.MIplImage;
- MIplImage d = img.MIplImage;
- byte* dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- byte* px, o_px;
- int width = imgCopy.Width;
- int height = imgCopy.Height;
- int widthStep = m.widthStep;
- int nChan = m.nChannels; // number of channels - 3
- int padding = widthStep - nChan * width;
- int x, y;
- int x_blk_inf = 0, x_blk_sup = 0, y_blk_inf = 0, y_blk_sup = 0;
- int x_img_inf = 0, x_img_sup = 0, y_img_inf = 0, y_img_sup = 0;
- if (dx > 0)
- {
- x_blk_inf = 0;
- x_blk_sup = dx;
- x_img_inf = dx;
- x_img_sup = width;
- }
- else if (dx < 0)
- {
- x_img_inf = 0;
- x_img_sup = width + dx;
- x_blk_inf = width + dx;
- x_blk_sup = width;
- }
- if (dy > 0)
- {
- y_blk_inf = 0;
- y_blk_sup = dy;
- y_img_inf = dy;
- y_img_sup = height;
- }
- else if (dy < 0)
- {
- y_img_inf = 0;
- y_img_sup = height + dy;
- y_blk_inf = height + dy;
- y_blk_sup = height;
- }
- if (nChan == 3) // image in RGB
- {
- // Process dx bigger rectangle
- for (y = 0; y < height; y++)
- {
- for (x = x_blk_inf; x < x_blk_sup; x++)
- {
- px = (dataPtr + y * widthStep + x * nChan);
- px[0] = 0;
- px[1] = 0;
- px[2] = 0;
- }
- }
- // Process dy smaller rectangle
- for (y = y_blk_inf; y < y_blk_sup; y++)
- {
- for (x = x_img_inf; x < x_img_sup; x++)
- {
- px = (dataPtr + y * widthStep + x * nChan);
- px[0] = 0;
- px[1] = 0;
- px[2] = 0;
- }
- }
- // Process image rectangle
- for (y = y_img_inf; y < y_img_sup; y++)
- {
- for (x = y_img_inf; x < x_img_sup; x++)
- {
- px = (dataPtr + y * widthStep + x * nChan);
- o_px = (dataPtr_org + (y - dy) * widthStep + (x - dx) * nChan);
- // Change Pixels
- px[0] = (byte)o_px[0];
- px[1] = (byte)o_px[1];
- px[2] = (byte)o_px[2];
- }
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Translation - Segmented
- public static void Rotation(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, float angle)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- MIplImage m1 = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrCopy = (byte*)m1.imageData.ToPointer(); // Pointer to the image
- byte* pxCopy;
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- int x, y;
- double sin = Math.Sin(angle);
- double cos = Math.Cos(angle);
- double xc = (-((double)width / 2) * cos) - (((double)height / 2) * sin) + ((double)width / 2);
- double yc = (((double)width / 2) * sin) - (((double)height / 2) * cos) + ((double)height / 2);
- int xo, yo;
- if (nChan == 3)
- {
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- xo = (int)Math.Round(xc + x * cos + y * sin);
- yo = (int)Math.Round(yc - x * sin + y * cos);
- // calcula endereço do pixel no ponto (x,y)
- if ((xo >= 0 && xo < width) && (yo >= 0 && yo < height))
- {
- pxCopy = (dataPtrCopy + yo * m.widthStep + xo * nChan);
- dataPtr[0] = (byte)pxCopy[0];
- dataPtr[1] = (byte)pxCopy[1];
- dataPtr[2] = (byte)pxCopy[2];
- }
- else
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- }
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Rotation
- public static void Rotation_Bilinear(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, float angle)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- MIplImage m1 = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrCopy = (byte*)m1.imageData.ToPointer(); // Pointer to the image
- byte* px, pxCopy;
- byte* a, b, c, d;
- int width = img.Width;
- int height = img.Height;
- int widthStep = m.widthStep;
- int nChan = m.nChannels; // number of channels - 3
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- int x, y;
- double sin = Math.Sin(angle);
- double cos = Math.Cos(angle);
- double xc = (-((double)width / 2) * cos) - (((double)height / 2) * sin) + ((double)width / 2);
- double yc = (((double)width / 2) * sin) - (((double)height / 2) * cos) + ((double)height / 2);
- double xo, yo;
- double j, k;
- double blueS, greenS, redS;
- double blueI, greenI, redI;
- int xr, yr; // reduzido ?
- if (nChan == 3)
- {
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- xo = xc + x * cos + y * sin;
- yo = yc - x * sin + y * cos;
- j = xo % 1; // parte decimal da coordenada em x
- k = yo % 1; // parte decimal da coordenada em y
- xr = (int)(xo - j);
- yr = (int)(yo - k);
- // calcula endereço do pixel no ponto (x,y)
- if ((xo >= 0 && xo < width) && (yo >= 0 && yo < height))
- {
- if (xo >= width - 1)
- xr = width - 2; // para não passar da imagem quando (xr + 1)
- if (yo >= height - 1)
- yr = height - 2; // para não passar da imagem quando (yr + 1)
- pxCopy = (dataPtrCopy + yr * widthStep + xr * nChan);
- a = (pxCopy);
- b = (pxCopy + nChan);
- c = (pxCopy + widthStep);
- d = (pxCopy + nChan + widthStep);
- // Bx+j,y = (1 - j) * Bx,y + j * Bx+1,y
- blueS = (1 - j) * a[0] + j * b[0];
- greenS = (1 - j) * a[1] + j * b[1];
- redS = (1 - j) * a[2] + j * b[2];
- // Bx+j,y+1 = (1 - j) * Bx,y+1 + j * Bx+1,y+1
- blueI = (1 - j) * c[0] + j * d[0];
- greenI = (1 - j) * c[1] + j * d[1];
- redI = (1 - j) * c[2] + j * d[2];
- // Bx+j,y+k = (1 - k) * Bx+j,y + k * Bx+j,y+1
- dataPtr[0] = (byte)(Math.Round((1 - k) * blueS + k * blueI));
- dataPtr[1] = (byte)(Math.Round((1 - k) * greenS + k * greenI));
- dataPtr[2] = (byte)(Math.Round((1 - k) * redS + k * redI));
- }
- else
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- }
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Rotation Bilinear
- public static void Scale(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, float scaleFactor)
- {
- unsafe
- {
- MIplImage m = imgCopy.MIplImage;
- MIplImage d = img.MIplImage;
- byte* dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- byte* o_px;
- int w = img.Width, h = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = widthStep - nChan * w;
- int x, y, x_org, y_org;
- if (nChan == 3) // image in RGB
- {
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- x_org = (int)Math.Round(x / scaleFactor);
- y_org = (int)Math.Round(y / scaleFactor);
- o_px = dataPtr_org + y_org * widthStep + x_org * nChan;
- // Outside of borders
- if (x_org < 0 || x_org >= w || y_org < 0 || y_org >= h)
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- dataPtr += nChan;
- continue;
- }
- // Change Pixels
- dataPtr[0] = o_px[0];
- dataPtr[1] = o_px[1];
- dataPtr[2] = o_px[2];
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Scale
- public static void Scale_Bilinear(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, float scaleFactor)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- MIplImage m1 = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrCopy = (byte*)m1.imageData.ToPointer(); // Pointer to the image
- byte* px, pxCopy;
- byte* a, b, c, d;
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- int x, y;
- double xo, yo;
- double j, k;
- double blueS, greenS, redS;
- double blueI, greenI, redI;
- int xr, yr; // reduzido ?
- if (nChan == 3)
- {
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- xo = x / scaleFactor;
- yo = y / scaleFactor;
- j = xo % 1; // parte decimal da coordenada em x
- k = yo % 1; // parte decimal da coordenada em y
- xr = (int)(xo - j);
- yr = (int)(yo - k);
- // calcula endereço do pixel no ponto (x,y)
- if ((xo >= 0 && xo < width) && (yo >= 0 && yo < height))
- {
- if (xo == width - 1)
- xr--; // para não passar da imagem quando (xr + 1)
- if (yo == height - 1)
- yr--; // para não passar da imagem quando (yr + 1)
- pxCopy = (dataPtrCopy + yr * widthStep + xr * nChan);
- a = (pxCopy);
- b = (pxCopy + nChan);
- c = (pxCopy + widthStep);
- d = (pxCopy + nChan + widthStep);
- // Bx+j,y = (1 - j) * Bx,y + j * Bx+1,y
- blueS = (1 - j) * a[0] + j * b[0];
- greenS = (1 - j) * a[1] + j * b[1];
- redS = (1 - j) * a[2] + j * b[2];
- // Bx+j,y+1 = (1 - j) * Bx,y+1 + j * Bx+1,y+1
- blueI = (1 - j) * c[0] + j * d[0];
- greenI = (1 - j) * c[1] + j * d[1];
- redI = (1 - j) * c[2] + j * d[2];
- // Bx+j,y+k = (1 - k) * Bx+j,y + k * Bx+j,y+1
- dataPtr[0] = (byte)(Math.Round((1 - k) * blueS + k * blueI));
- dataPtr[1] = (byte)(Math.Round((1 - k) * greenS + k * greenI));
- dataPtr[2] = (byte)(Math.Round((1 - k) * redS + k * redI));
- }
- else
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- }
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Scale Bilinear
- public static void Scale_point_xy(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, float scaleFactor, int centerX, int centerY)
- {
- unsafe
- {
- MIplImage m = imgCopy.MIplImage;
- MIplImage f = img.MIplImage;
- byte* dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- byte* dataPtr = (byte*)f.imageData.ToPointer(); // Pointer to the final image
- byte* px_org;
- int w = img.Width, h = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = widthStep - nChan * w;
- int x, y, x_aux, y_aux;
- int w2 = w / 2, h2 = h / 2;
- float w2s = w2 / scaleFactor, h2s = h2 / scaleFactor;
- if (nChan == 3) // image in RGB
- {
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- x_aux = (int)Math.Round(centerX + (x / scaleFactor) - w2s);
- y_aux = (int)Math.Round(centerY + (y / scaleFactor) - h2s);
- px_org = dataPtr_org + y_aux * widthStep + x_aux * nChan;
- // Outside of borders
- if (x_aux < 0 || x_aux >= w || y_aux < 0 || y_aux >= h)
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- dataPtr += nChan;
- continue;
- }
- dataPtr[0] = px_org[0];
- dataPtr[1] = px_org[1];
- dataPtr[2] = px_org[2];
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Scale Point XY Bilinear
- public static void Scale_point_xy_Bilinear(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, float scaleFactor, int centerX, int centerY)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- MIplImage m1 = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrCopy = (byte*)m1.imageData.ToPointer(); // Pointer to the image
- byte* px, pxCopy;
- byte* a, b, c, d;
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- int x, y, Xcent, Ycent;
- double xo, yo;
- double j, k;
- double blueS, greenS, redS;
- double blueI, greenI, redI;
- int xr, yr; // reduzido ?
- Xcent = width / 2;
- Ycent = height / 2;
- if (scaleFactor < 1) //se scale < 1, inverter o referencial de zoom. (diminui a imagem, mantendo o pÃxel da posição do rato inalterado)
- {
- centerX = m.width - centerX;
- centerY = m.height - centerY;
- }
- if (nChan == 3)
- {
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- //mudar o referencial para o centro da image, e deslocá-la para (mouseX,mouseY)
- xo = (x - Xcent) / scaleFactor + centerX;
- yo = (y - Ycent) / scaleFactor + centerY;
- j = xo % 1; // parte decimal da coordenada em x
- k = yo % 1; // parte decimal da coordenada em y
- xr = (int)(xo - j);
- yr = (int)(yo - k);
- //px = (dataPtr + y * widthStep + x * nChan);
- // calcula endereço do pixel no ponto (x,y)
- if ((xo >= 0 && xo < width) && (yo >= 0 && yo < height))
- {
- // Neste caso não é estritamente necessário porque é muito difÃcil o rato ficar na posição (0;0), com scaleFactor = 1, mas por motivos de segurança, fica no código
- if (xo == width - 1)
- xr--; // para não passar da imagem quando (xr + 1)
- if (yo == height - 1)
- yr--; // para não passar da imagem quando (yr + 1)
- pxCopy = (dataPtrCopy + yr * widthStep + xr * nChan);
- a = (pxCopy);
- b = (pxCopy + nChan);
- c = (pxCopy + widthStep);
- d = (pxCopy + nChan + widthStep);
- // Bx+j,y = (1 - j) * Bx,y + j * Bx+1,y
- blueS = (1 - j) * a[0] + j * b[0];
- greenS = (1 - j) * a[1] + j * b[1];
- redS = (1 - j) * a[2] + j * b[2];
- // Bx+j,y+1 = (1 - j) * Bx,y+1 + j * Bx+1,y+1
- blueI = (1 - j) * c[0] + j * d[0];
- greenI = (1 - j) * c[1] + j * d[1];
- redI = (1 - j) * c[2] + j * d[2];
- // Bx+j,y+k = (1 - k) * Bx+j,y + k * Bx+j,y+1
- dataPtr[0] = (byte)(Math.Round((1 - k) * blueS + k * blueI));
- dataPtr[1] = (byte)(Math.Round((1 - k) * greenS + k * greenI));
- dataPtr[2] = (byte)(Math.Round((1 - k) * redS + k * redI));
- }
- else
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- }
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Scale Point XY Bilinear
- public static void Mean(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy)
- {
- unsafe
- {
- MIplImage m = imgCopy.MIplImage;
- MIplImage d = img.MIplImage;
- byte* dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- byte* centerPx, o_centerPx;
- int w = img.Width;
- int h = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = widthStep - nChan * w;
- int x, y;
- double[] sum = new double[3];
- if (nChan == 3) // image in RGB
- {
- // *** Corners ***
- {
- // Top Left x = 0; y = 0;
- o_centerPx = dataPtr_org;
- centerPx = dataPtr;
- sum[0] = (o_centerPx)[0] * 4
- + (o_centerPx + nChan)[0] * 2
- + (o_centerPx + widthStep)[0] * 2
- + (o_centerPx + widthStep + nChan)[0];
- sum[1] = (o_centerPx)[1] * 4
- + (o_centerPx + nChan)[1] * 2
- + (o_centerPx + widthStep)[1] * 2
- + (o_centerPx + widthStep + nChan)[1];
- sum[2] = (o_centerPx)[2] * 4
- + (o_centerPx + nChan)[2] * 2
- + (o_centerPx + widthStep)[2] * 2
- + (o_centerPx + widthStep + nChan)[2];
- centerPx[0] = (byte)Math.Round(sum[0] / 9.0);
- centerPx[1] = (byte)Math.Round(sum[1] / 9.0);
- centerPx[2] = (byte)Math.Round(sum[2] / 9.0);
- // Top Right x = w - 1; y = 0;
- o_centerPx = dataPtr_org + (w - 1) * nChan;
- centerPx = dataPtr + (w - 1) * nChan;
- sum[0] = (o_centerPx)[0] * 4
- + (o_centerPx - nChan)[0] * 2
- + (o_centerPx + widthStep)[0] * 2
- + (o_centerPx + widthStep - nChan)[0];
- sum[1] = (o_centerPx)[1] * 4
- + (o_centerPx - nChan)[1] * 2
- + (o_centerPx + widthStep)[1] * 2
- + (o_centerPx + widthStep - nChan)[1];
- sum[2] = (o_centerPx)[2] * 4
- + (o_centerPx - nChan)[2] * 2
- + (o_centerPx + widthStep)[2] * 2
- + (o_centerPx + widthStep - nChan)[2];
- centerPx[0] = (byte)Math.Round(sum[0] / 9.0);
- centerPx[1] = (byte)Math.Round(sum[1] / 9.0);
- centerPx[2] = (byte)Math.Round(sum[2] / 9.0);
- // Bottom Left x = 0; y = h - 1;
- o_centerPx = dataPtr_org + (h - 1) * widthStep;
- centerPx = dataPtr + (h - 1) * widthStep;
- sum[0] = (o_centerPx)[0] * 4
- + (o_centerPx + nChan)[0] * 2
- + (o_centerPx - widthStep)[0] * 2
- + (o_centerPx - widthStep + nChan)[0];
- sum[1] = (o_centerPx)[1] * 4
- + (o_centerPx + nChan)[1] * 2
- + (o_centerPx - widthStep)[1] * 2
- + (o_centerPx - widthStep + nChan)[1];
- sum[2] = (o_centerPx)[2] * 4
- + (o_centerPx + nChan)[2] * 2
- + (o_centerPx - widthStep)[2] * 2
- + (o_centerPx - widthStep + nChan)[2];
- centerPx[0] = (byte)Math.Round(sum[0] / 9.0);
- centerPx[1] = (byte)Math.Round(sum[1] / 9.0);
- centerPx[2] = (byte)Math.Round(sum[2] / 9.0);
- // Bottom Right x = w - 1; y = h - 1;
- o_centerPx = dataPtr_org + (h - 1) * widthStep + (w - 1) * nChan;
- centerPx = dataPtr + (h - 1) * widthStep + (w - 1) * nChan;
- sum[0] = (o_centerPx)[0] * 4
- + (o_centerPx - nChan)[0] * 2
- + (o_centerPx - widthStep)[0] * 2
- + (o_centerPx - widthStep - nChan)[0];
- sum[1] = (o_centerPx)[1] * 4
- + (o_centerPx - nChan)[1] * 2
- + (o_centerPx - widthStep)[1] * 2
- + (o_centerPx - widthStep - nChan)[1];
- sum[2] = (o_centerPx)[2] * 4
- + (o_centerPx - nChan)[2] * 2
- + (o_centerPx - widthStep)[2] * 2
- + (o_centerPx - widthStep - nChan)[2];
- centerPx[0] = (byte)Math.Round(sum[0] / 9.0);
- centerPx[1] = (byte)Math.Round(sum[1] / 9.0);
- centerPx[2] = (byte)Math.Round(sum[2] / 9.0);
- }
- // *** BORDERS ***
- {
- // Left
- for (y = 1; y < h - 1; y++)
- {
- dataPtr += widthStep;
- dataPtr_org += widthStep;
- sum[0] = (dataPtr_org - widthStep)[0] * 2
- + (dataPtr_org - widthStep + nChan)[0]
- + (dataPtr_org)[0] * 2
- + (dataPtr_org + nChan)[0]
- + (dataPtr_org + widthStep)[0] * 2
- + (dataPtr_org + widthStep + nChan)[0];
- sum[1] = (dataPtr_org - widthStep)[1] * 2
- + (dataPtr_org - widthStep + nChan)[1]
- + (dataPtr_org)[1] * 2
- + (dataPtr_org + nChan)[1]
- + (dataPtr_org + widthStep)[1] * 2
- + (dataPtr_org + widthStep + nChan)[1];
- sum[2] = (dataPtr_org - widthStep)[2] * 2
- + (dataPtr_org - widthStep + nChan)[2]
- + (dataPtr_org)[2] * 2
- + (dataPtr_org + nChan)[2]
- + (dataPtr_org + widthStep)[2] * 2
- + (dataPtr_org + widthStep + nChan)[2];
- dataPtr[0] = (byte)Math.Round(sum[0] / 9.0);
- dataPtr[1] = (byte)Math.Round(sum[1] / 9.0);
- dataPtr[2] = (byte)Math.Round(sum[2] / 9.0);
- }
- dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- dataPtr += nChan * (w - 1);
- dataPtr_org += nChan * (w - 1);
- // Right
- for (y = 1; y < h - 1; y++)
- {
- dataPtr += widthStep;
- dataPtr_org += widthStep;
- sum[0] = (dataPtr_org - widthStep)[0] * 2
- + (dataPtr_org - widthStep - nChan)[0]
- + (dataPtr_org)[0] * 2
- + (dataPtr_org - nChan)[0]
- + (dataPtr_org + widthStep)[0] * 2
- + (dataPtr_org + widthStep - nChan)[0];
- sum[1] = (dataPtr_org - widthStep)[1] * 2
- + (dataPtr_org - widthStep - nChan)[1]
- + (dataPtr_org)[1] * 2
- + (dataPtr_org - nChan)[1]
- + (dataPtr_org + widthStep)[1] * 2
- + (dataPtr_org + widthStep - nChan)[1];
- sum[2] = (dataPtr_org - widthStep)[2] * 2
- + (dataPtr_org - widthStep - nChan)[2]
- + (dataPtr_org)[2] * 2
- + (dataPtr_org - nChan)[2]
- + (dataPtr_org + widthStep)[2] * 2
- + (dataPtr_org + widthStep - nChan)[2];
- dataPtr[0] = (byte)Math.Round(sum[0] / 9.0);
- dataPtr[1] = (byte)Math.Round(sum[1] / 9.0);
- dataPtr[2] = (byte)Math.Round(sum[2] / 9.0);
- }
- dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- // Top
- for (x = 1; x < w - 1; x++)
- {
- dataPtr += nChan;
- dataPtr_org += nChan;
- sum[0] = (dataPtr_org - nChan)[0] * 2
- + (dataPtr_org)[0] * 2
- + (dataPtr_org + nChan)[0] * 2
- + (dataPtr_org + widthStep - nChan)[0]
- + (dataPtr_org + widthStep)[0]
- + (dataPtr_org + widthStep + nChan)[0];
- sum[1] = (dataPtr_org - nChan)[1] * 2
- + (dataPtr_org)[1] * 2
- + (dataPtr_org + nChan)[1] * 2
- + (dataPtr_org + widthStep - nChan)[1]
- + (dataPtr_org + widthStep)[1]
- + (dataPtr_org + widthStep + nChan)[1];
- sum[2] = (dataPtr_org - nChan)[2] * 2
- + (dataPtr_org)[2] * 2
- + (dataPtr_org + nChan)[2] * 2
- + (dataPtr_org + widthStep - nChan)[2]
- + (dataPtr_org + widthStep)[2]
- + (dataPtr_org + widthStep + nChan)[2];
- dataPtr[0] = (byte)Math.Round(sum[0] / 9.0);
- dataPtr[1] = (byte)Math.Round(sum[1] / 9.0);
- dataPtr[2] = (byte)Math.Round(sum[2] / 9.0);
- }
- dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- dataPtr += (h - 1) * widthStep;
- dataPtr_org += (h - 1) * widthStep;
- // Bottom
- for (x = 1; x < w - 1; x++)
- {
- dataPtr += nChan;
- dataPtr_org += nChan;
- sum[0] = (dataPtr_org - widthStep - nChan)[0]
- + (dataPtr_org - widthStep)[0]
- + (dataPtr_org - widthStep + nChan)[0]
- + (dataPtr_org - nChan)[0] * 2
- + (dataPtr_org)[0] * 2
- + (dataPtr_org + nChan)[0] * 2;
- sum[1] = (dataPtr_org - widthStep - nChan)[1]
- + (dataPtr_org - widthStep)[1]
- + (dataPtr_org - widthStep + nChan)[1]
- + (dataPtr_org - nChan)[1] * 2
- + (dataPtr_org)[1] * 2
- + (dataPtr_org + nChan)[1] * 2;
- sum[2] = (dataPtr_org - widthStep - nChan)[2]
- + (dataPtr_org - widthStep)[2]
- + (dataPtr_org - widthStep + nChan)[2]
- + (dataPtr_org - nChan)[2] * 2
- + (dataPtr_org)[2] * 2
- + (dataPtr_org + nChan)[2] * 2;
- dataPtr[0] = (byte)Math.Round(sum[0] / 9.0);
- dataPtr[1] = (byte)Math.Round(sum[1] / 9.0);
- dataPtr[2] = (byte)Math.Round(sum[2] / 9.0);
- }
- dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- dataPtr += widthStep + nChan;
- dataPtr_org += widthStep + nChan;
- }
- // *** CORE ***
- for (y = 1; y < h - 1; y++)
- {
- for (x = 1; x < w - 1; x++)
- {
- sum[0] = (dataPtr_org - widthStep - nChan)[0]
- + (dataPtr_org - widthStep)[0]
- + (dataPtr_org - widthStep + nChan)[0]
- + (dataPtr_org - nChan)[0]
- + (dataPtr_org)[0]
- + (dataPtr_org + nChan)[0]
- + (dataPtr_org + widthStep - nChan)[0]
- + (dataPtr_org + widthStep)[0]
- + (dataPtr_org + widthStep + nChan)[0];
- sum[1] = (dataPtr_org - widthStep - nChan)[1]
- + (dataPtr_org - widthStep)[1]
- + (dataPtr_org - widthStep + nChan)[1]
- + (dataPtr_org - nChan)[1]
- + (dataPtr_org)[1]
- + (dataPtr_org + nChan)[1]
- + (dataPtr_org + widthStep - nChan)[1]
- + (dataPtr_org + widthStep)[1]
- + (dataPtr_org + widthStep + nChan)[1];
- sum[2] = (dataPtr_org - widthStep - nChan)[2]
- + (dataPtr_org - widthStep)[2]
- + (dataPtr_org - widthStep + nChan)[2]
- + (dataPtr_org - nChan)[2]
- + (dataPtr_org)[2]
- + (dataPtr_org + nChan)[2]
- + (dataPtr_org + widthStep - nChan)[2]
- + (dataPtr_org + widthStep)[2]
- + (dataPtr_org + widthStep + nChan)[2];
- dataPtr[0] = (byte)Math.Round(sum[0] / 9.0);
- dataPtr[1] = (byte)Math.Round(sum[1] / 9.0);
- dataPtr[2] = (byte)Math.Round(sum[2] / 9.0);
- dataPtr += nChan;
- dataPtr_org += nChan;
- }
- dataPtr += padding + 2 * nChan;
- dataPtr_org += padding + 2 * nChan;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Mean
- public static void Mean_solutionB(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy)
- {
- unsafe
- {
- // direct access to the image memory(sequencial)
- // direcion top left -> bottom right
- MIplImage m = img.MIplImage;
- MIplImage m1 = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrred = dataPtr;
- byte* auxdataPtr = (byte*)m1.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrStatic = auxdataPtr; // Pointer de referência para o inÃcio da imagem a editar
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- int x = 0, y = 0;
- float Iblue, Igreen, Ired;
- float Iblueaux, Igreenaux, Iredaux;
- float blueSUM, greenSUM, redSUM;
- if (nChan == 3)
- {
- //y = 0, 0 <= x < width
- Iblue = 4 * dataPtrStatic[0];
- Igreen = 4 * dataPtrStatic[1];
- Ired = 4 * dataPtrStatic[2];
- Iblue += 2 * (dataPtrStatic + nChan)[0];
- Igreen += 2 * (dataPtrStatic + nChan)[1];
- Ired += 2 * (dataPtrStatic + nChan)[2];
- Iblue += (dataPtrStatic + m.widthStep + nChan)[0];
- Igreen += (dataPtrStatic + m.widthStep + nChan)[1];
- Ired += (dataPtrStatic + m.widthStep + nChan)[2];
- Iblue += 2 * (dataPtrStatic + m.widthStep)[0];
- Igreen += 2 * (dataPtrStatic + m.widthStep)[1];
- Ired += 2 * (dataPtrStatic + m.widthStep)[2];
- Iblueaux = Iblue;
- Igreenaux = Igreen;
- Iredaux = Ired;
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- //y = 0, x = 1
- x++;
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[0] - 2 * (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[0];
- Igreen += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[1] - 2 * (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[1];
- Ired += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[2] - 2 * (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 1) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 1) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 1) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- //y = 0, x = 2
- for (x = 2; x < width - 1; x++)
- {
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[0] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[0];
- Igreen += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[1] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[1];
- Ired += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[2] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- //x = width - 1
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += 2 * (dataPtrStatic + y * m.widthStep + x * nChan)[0] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[0];
- Igreen += 2 * (dataPtrStatic + y * m.widthStep + x * nChan)[1] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[1];
- Ired += 2 * (dataPtrStatic + y * m.widthStep + x * nChan)[2] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[0] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[1] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[2] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- x = 0;
- y = 1;
- // y = 1, x = 0
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue = Iblueaux;
- Igreen = Igreenaux;
- Ired = Iredaux;
- Iblue += 2 * (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[0] - 2 * (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[0];
- Igreen += 2 * (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[1] - 2 * (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[1];
- Ired += 2 * (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[2] - 2 * (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[2];
- Iblueaux = Iblue;
- Igreenaux = Igreen;
- Iredaux = Ired;
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- // y = 1, x = 1
- x = 1;
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 1) * nChan)[0];
- Igreen += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 1) * nChan)[1];
- Ired += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 1) * nChan)[2];
- Iblue += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[0];
- Igreen += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[1];
- Ired += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 1) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 1) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 1) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- for (x = 2; x < width - 1; x++)
- {
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- // x = width - 1
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + y * m.widthStep + x * nChan)[0] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + y * m.widthStep + x * nChan)[1] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + y * m.widthStep + x * nChan)[2] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[0] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[1] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[2] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- // 1 < y < height, 0 <= x < width
- for (y = 2; y < height - 1; y++)
- {
- // x = 0
- x = 0;
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue = Iblueaux;
- Igreen = Igreenaux;
- Ired = Iredaux;
- Iblue += 2 * (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[0] - 2 * (dataPtrStatic + (y - 2) * m.widthStep + x * nChan)[0];
- Igreen += 2 * (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[1] - 2 * (dataPtrStatic + (y - 2) * m.widthStep + x * nChan)[1];
- Ired += 2 * (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[2] - 2 * (dataPtrStatic + (y - 2) * m.widthStep + x * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y - 2) * m.widthStep + (x + 1) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y - 2) * m.widthStep + (x + 1) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y - 2) * m.widthStep + (x + 1) * nChan)[2];
- Iblueaux = Iblue;
- Igreenaux = Igreen;
- Iredaux = Ired;
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- // x = 1
- x = 1;
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 1) * nChan)[0];
- Igreen += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 1) * nChan)[1];
- Ired += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 1) * nChan)[2];
- Iblue += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[0];
- Igreen += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[1];
- Ired += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 1) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 1) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 1) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- // x = 2
- for (x = 2; x < width - 1; x++)
- {
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- // x = width - 1
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + y * m.widthStep + x * nChan)[0] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + y * m.widthStep + x * nChan)[1] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + y * m.widthStep + x * nChan)[2] - (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[0] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[1] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y + 1) * m.widthStep + x * nChan)[2] - (dataPtrStatic + (y + 1) * m.widthStep + (x - 2) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- // y = height - 1, x = 0
- x = 0;
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue = Iblueaux;
- Igreen = Igreenaux;
- Ired = Iredaux;
- Iblue += 2 * (dataPtrStatic + y * m.widthStep + x * nChan)[0] - 2 * (dataPtrStatic + (y - 2) * m.widthStep + x * nChan)[0];
- Igreen += 2 * (dataPtrStatic + y * m.widthStep + x * nChan)[1] - 2 * (dataPtrStatic + (y - 2) * m.widthStep + x * nChan)[1];
- Ired += 2 * (dataPtrStatic + y * m.widthStep + x * nChan)[2] - 2 * (dataPtrStatic + (y - 2) * m.widthStep + x * nChan)[2];
- Iblue += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y - 2) * m.widthStep + (x + 1) * nChan)[0];
- Igreen += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y - 2) * m.widthStep + (x + 1) * nChan)[1];
- Ired += (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y - 2) * m.widthStep + (x + 1) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- x = 1;
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[0] - 2 * (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[0];
- Igreen += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[1] - 2 * (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[1];
- Ired += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[2] - 2 * (dataPtrStatic + y * m.widthStep + (x - 1) * nChan)[2];
- Iblue += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 1) * nChan)[0];
- Igreen += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 1) * nChan)[1];
- Ired += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 1) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- // x = 2
- for (x = 2; x < width - 1; x++)
- {
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[0] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[0];
- Igreen += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[1] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[1];
- Ired += 2 * (dataPtrStatic + y * m.widthStep + (x + 1) * nChan)[2] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y - 1) * m.widthStep + (x + 1) * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- // x = width - 1
- dataPtr = dataPtrred + y * m.widthStep + x * nChan;
- Iblue += 2 * (dataPtrStatic + y * m.widthStep + x * nChan)[0] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[0];
- Igreen += 2 * (dataPtrStatic + y * m.widthStep + x * nChan)[1] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[1];
- Ired += 2 * (dataPtrStatic + y * m.widthStep + x * nChan)[2] - 2 * (dataPtrStatic + y * m.widthStep + (x - 2) * nChan)[2];
- Iblue += (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[0] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[0];
- Igreen += (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[1] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[1];
- Ired += (dataPtrStatic + (y - 1) * m.widthStep + x * nChan)[2] - (dataPtrStatic + (y - 1) * m.widthStep + (x - 2) * nChan)[2];
- blueSUM = (float)Math.Round(Iblue / 9);
- greenSUM = (float)Math.Round(Igreen / 9);
- redSUM = (float)Math.Round(Ired / 9);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- }
- } // End of Mean Solution B
- // Non Uniform Corrente -> Faster but with more errors
- public static void NonUniform_Marco(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, float[,] matrix, float matrixWeight)
- {
- unsafe
- {
- MIplImage m = imgCopy.MIplImage;
- MIplImage d = img.MIplImage;
- byte* dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- byte* centerPx, o_centerPx;
- int w = img.Width;
- int h = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int x, y;
- double[] sum = new double[3];
- double[] w_sum = new double[3];
- if (nChan == 3) // image in RGB
- {
- // *** Corners ***
- // Top Left
- x = 0; y = 0;
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- sum[0] = (o_centerPx)[0] * (matrix[1, 1] + matrix[0, 0] + matrix[0, 1] + matrix[1, 0])
- + (o_centerPx + nChan)[0] * (matrix[2, 1] + matrix[2, 0])
- + (o_centerPx + widthStep)[0] * (matrix[1, 2] + matrix[0, 2])
- + (o_centerPx + widthStep + nChan)[0] * (matrix[2, 2]);
- sum[1] = (o_centerPx)[1] * (matrix[1, 1] + matrix[0, 0] + matrix[0, 1] + matrix[1, 0])
- + (o_centerPx + nChan)[1] * (matrix[2, 1] + matrix[2, 0])
- + (o_centerPx + widthStep)[1] * (matrix[1, 2] + matrix[0, 2])
- + (o_centerPx + widthStep + nChan)[1] * (matrix[2, 2]);
- sum[2] = (o_centerPx)[2] * (matrix[1, 1] + matrix[0, 0] + matrix[0, 1] + matrix[1, 0])
- + (o_centerPx + nChan)[2] * (matrix[2, 1] + matrix[2, 0])
- + (o_centerPx + widthStep)[2] * (matrix[1, 2] + matrix[0, 2])
- + (o_centerPx + widthStep + nChan)[2] * (matrix[2, 2]);
- w_sum[0] = Math.Round(sum[0] / matrixWeight);
- w_sum[1] = Math.Round(sum[1] / matrixWeight);
- w_sum[2] = Math.Round(sum[2] / matrixWeight);
- centerPx[0] = (byte)(w_sum[0] > 255 ? 255 : (w_sum[0] < 0) ? 0 : w_sum[0]);
- centerPx[1] = (byte)(w_sum[1] > 255 ? 255 : (w_sum[1] < 0) ? 0 : w_sum[1]);
- centerPx[2] = (byte)(w_sum[2] > 255 ? 255 : (w_sum[2] < 0) ? 0 : w_sum[2]);
- // Top Right
- x = w - 1; y = 0;
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- sum[0] = (o_centerPx)[0] * (matrix[2, 2] + matrix[1, 1] + matrix[1, 2] + matrix[2, 1])
- + (o_centerPx - nChan)[0] * (matrix[0, 1] + matrix[0, 0])
- + (o_centerPx + widthStep)[0] * (matrix[1, 2] + matrix[2, 2])
- + (o_centerPx + widthStep - nChan)[0] * (matrix[0, 2]);
- sum[1] = (o_centerPx)[1] * (matrix[2, 2] + matrix[1, 1] + matrix[1, 2] + matrix[2, 1])
- + (o_centerPx - nChan)[1] * (matrix[0, 1] + matrix[0, 0])
- + (o_centerPx + widthStep)[1] * (matrix[1, 2] + matrix[2, 2])
- + (o_centerPx + widthStep - nChan)[1] * (matrix[0, 2]);
- sum[2] = (o_centerPx)[2] * (matrix[2, 2] + matrix[1, 1] + matrix[1, 2] + matrix[2, 1])
- + (o_centerPx - nChan)[2] * (matrix[0, 1] + matrix[0, 0])
- + (o_centerPx + widthStep)[2] * (matrix[1, 2] + matrix[2, 2])
- + (o_centerPx + widthStep - nChan)[2] * (matrix[0, 2]);
- w_sum[0] = Math.Round(sum[0] / matrixWeight);
- w_sum[1] = Math.Round(sum[1] / matrixWeight);
- w_sum[2] = Math.Round(sum[2] / matrixWeight);
- centerPx[0] = (byte)(w_sum[0] > 255 ? 255 : (w_sum[0] < 0) ? 0 : w_sum[0]);
- centerPx[1] = (byte)(w_sum[1] > 255 ? 255 : (w_sum[1] < 0) ? 0 : w_sum[1]);
- centerPx[2] = (byte)(w_sum[2] > 255 ? 255 : (w_sum[2] < 0) ? 0 : w_sum[2]);
- // Bottom Left
- x = 0; y = h - 1;
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- sum[0] = (o_centerPx)[0] * (matrix[1, 1] + matrix[2, 2] + matrix[2, 1] + matrix[1, 2])
- + (o_centerPx + nChan)[0] * (matrix[2, 1] + matrix[2, 2])
- + (o_centerPx - widthStep)[0] * (matrix[1, 0] + matrix[0, 0])
- + (o_centerPx - widthStep + nChan)[0] * matrix[2, 0];
- sum[1] = (o_centerPx)[1] * (matrix[1, 1] + matrix[2, 2] + matrix[2, 1] + matrix[1, 2])
- + (o_centerPx + nChan)[1] * (matrix[2, 1] + matrix[2, 2])
- + (o_centerPx - widthStep)[1] * (matrix[1, 0] + matrix[0, 0])
- + (o_centerPx - widthStep + nChan)[1] * matrix[0, 2];
- sum[2] = (o_centerPx)[2] * (matrix[1, 1] + matrix[2, 2] + matrix[2, 1] + matrix[1, 2])
- + (o_centerPx + nChan)[2] * (matrix[2, 1] + matrix[2, 2])
- + (o_centerPx - widthStep)[2] * (matrix[1, 0] + matrix[0, 0])
- + (o_centerPx - widthStep + nChan)[2] * matrix[2, 0];
- w_sum[0] = Math.Round(sum[0] / matrixWeight);
- w_sum[1] = Math.Round(sum[1] / matrixWeight);
- w_sum[2] = Math.Round(sum[2] / matrixWeight);
- centerPx[0] = (byte)(w_sum[0] > 255 ? 255 : (w_sum[0] < 0) ? 0 : w_sum[0]);
- centerPx[1] = (byte)(w_sum[1] > 255 ? 255 : (w_sum[1] < 0) ? 0 : w_sum[1]);
- centerPx[2] = (byte)(w_sum[2] > 255 ? 255 : (w_sum[2] < 0) ? 0 : w_sum[2]);
- // Bottom Right
- x = w - 1; y = h - 1;
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- sum[0] = (o_centerPx)[0] * (matrix[1, 1] + matrix[2, 1] + matrix[1, 2] + matrix[2, 2])
- + (o_centerPx - nChan)[0] * (matrix[0, 1] + matrix[0, 2])
- + (o_centerPx - widthStep)[0] * (matrix[1, 0] + matrix[2, 0])
- + (o_centerPx - widthStep - nChan)[0] * matrix[0, 0];
- sum[1] = (o_centerPx)[1] * (matrix[1, 1] + matrix[2, 1] + matrix[1, 2] + matrix[2, 2])
- + (o_centerPx - nChan)[1] * (matrix[0, 1] + matrix[0, 2])
- + (o_centerPx - widthStep)[1] * (matrix[1, 0] + matrix[2, 0])
- + (o_centerPx - widthStep - nChan)[1] * matrix[0, 0];
- sum[2] = (o_centerPx)[2] * (matrix[1, 1] + matrix[2, 1] + matrix[1, 2] + matrix[2, 2])
- + (o_centerPx - nChan)[2] * (matrix[0, 1] + matrix[0, 2])
- + (o_centerPx - widthStep)[2] * (matrix[1, 0] + matrix[2, 0])
- + (o_centerPx - widthStep - nChan)[2] * matrix[0, 0];
- w_sum[0] = Math.Round(sum[0] / matrixWeight);
- w_sum[1] = Math.Round(sum[1] / matrixWeight);
- w_sum[2] = Math.Round(sum[2] / matrixWeight);
- centerPx[0] = (byte)(w_sum[0] > 255 ? 255 : (w_sum[0] < 0) ? 0 : w_sum[0]);
- centerPx[1] = (byte)(w_sum[1] > 255 ? 255 : (w_sum[1] < 0) ? 0 : w_sum[1]);
- centerPx[2] = (byte)(w_sum[2] > 255 ? 255 : (w_sum[2] < 0) ? 0 : w_sum[2]);
- // *** BORDERS ***
- // Left
- for (y = 1, x = 0; y < h - 1; y++)
- {
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- sum[0] = (o_centerPx - widthStep)[0] * (matrix[0, 0] + matrix[1, 0])
- + (o_centerPx - widthStep + nChan)[0] * (matrix[2, 0])
- + (o_centerPx)[0] * (matrix[0, 1] + matrix[1, 1])
- + (o_centerPx + nChan)[0] * (matrix[2, 1])
- + (o_centerPx + widthStep)[0] * (matrix[0, 2] + matrix[2, 2])
- + (o_centerPx + widthStep + nChan)[0] * (matrix[2, 2]);
- sum[1] = (o_centerPx - widthStep)[1] * (matrix[0, 0] + matrix[1, 0])
- + (o_centerPx - widthStep + nChan)[1] * (matrix[2, 0])
- + (o_centerPx)[1] * (matrix[0, 1] + matrix[1, 1])
- + (o_centerPx + nChan)[1] * (matrix[2, 1])
- + (o_centerPx + widthStep)[1] * (matrix[0, 2] + matrix[2, 2])
- + (o_centerPx + widthStep + nChan)[1] * (matrix[2, 2]);
- sum[2] = (o_centerPx - widthStep)[2] * (matrix[0, 0] + matrix[1, 0])
- + (o_centerPx - widthStep + nChan)[2] * (matrix[2, 0])
- + (o_centerPx)[2] * (matrix[0, 1] + matrix[1, 1])
- + (o_centerPx + nChan)[2] * (matrix[2, 1])
- + (o_centerPx + widthStep)[2] * (matrix[0, 2] + matrix[2, 2])
- + (o_centerPx + widthStep + nChan)[2] * (matrix[2, 2]);
- w_sum[0] = Math.Round(sum[0] / matrixWeight);
- w_sum[1] = Math.Round(sum[1] / matrixWeight);
- w_sum[2] = Math.Round(sum[2] / matrixWeight);
- centerPx[0] = (byte)(w_sum[0] > 255 ? 255 : (w_sum[0] < 0) ? 0 : w_sum[0]);
- centerPx[1] = (byte)(w_sum[1] > 255 ? 255 : (w_sum[1] < 0) ? 0 : w_sum[1]);
- centerPx[2] = (byte)(w_sum[2] > 255 ? 255 : (w_sum[2] < 0) ? 0 : w_sum[2]);
- }
- // Right
- for (y = 1, x = w - 1; y < h - 1; y++)
- {
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- sum[0] = (o_centerPx - widthStep)[0] * (matrix[0, 1] + matrix[2, 0])
- + (o_centerPx - widthStep - nChan)[0] * (matrix[0, 0])
- + (o_centerPx)[0] * (matrix[1, 1] + matrix[2, 1])
- + (o_centerPx - nChan)[0] * (matrix[0, 1])
- + (o_centerPx + widthStep)[0] * (matrix[1, 2] + matrix[2, 2])
- + (o_centerPx + widthStep - nChan)[0] * (matrix[0, 2]);
- sum[1] = (o_centerPx - widthStep)[1] * (matrix[0, 1] + matrix[2, 0])
- + (o_centerPx - widthStep - nChan)[1] * (matrix[0, 0])
- + (o_centerPx)[1] * (matrix[1, 1] + matrix[2, 1])
- + (o_centerPx - nChan)[1] * (matrix[0, 1])
- + (o_centerPx + widthStep)[1] * (matrix[1, 2] + matrix[2, 2])
- + (o_centerPx + widthStep - nChan)[1] * (matrix[0, 2]);
- sum[2] = (o_centerPx - widthStep)[2] * (matrix[0, 1] + matrix[2, 0])
- + (o_centerPx - widthStep - nChan)[2] * (matrix[0, 0])
- + (o_centerPx)[2] * (matrix[1, 1] + matrix[2, 1])
- + (o_centerPx - nChan)[2] * (matrix[0, 1])
- + (o_centerPx + widthStep)[2] * (matrix[1, 2] + matrix[2, 2])
- + (o_centerPx + widthStep - nChan)[2] * (matrix[0, 2]);
- w_sum[0] = Math.Round(sum[0] / matrixWeight);
- w_sum[1] = Math.Round(sum[1] / matrixWeight);
- w_sum[2] = Math.Round(sum[2] / matrixWeight);
- centerPx[0] = (byte)(w_sum[0] > 255 ? 255 : (w_sum[0] < 0) ? 0 : w_sum[0]);
- centerPx[1] = (byte)(w_sum[1] > 255 ? 255 : (w_sum[1] < 0) ? 0 : w_sum[1]);
- centerPx[2] = (byte)(w_sum[2] > 255 ? 255 : (w_sum[2] < 0) ? 0 : w_sum[2]);
- }
- // Top
- for (x = 1, y = 0; x < w - 1; x++)
- {
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- sum[0] = (o_centerPx - nChan)[0] * (matrix[0, 0] + matrix[0, 1])
- + (o_centerPx)[0] * (matrix[1, 1] + matrix[1, 0])
- + (o_centerPx + nChan)[0] * (matrix[2, 1] + matrix[2, 0])
- + (o_centerPx + widthStep - nChan)[0] * (matrix[0, 2])
- + (o_centerPx + widthStep)[0] * (matrix[1, 2])
- + (o_centerPx + widthStep + nChan)[0] * (matrix[2, 2]);
- sum[1] = (o_centerPx - nChan)[1] * (matrix[0, 0] + matrix[0, 1])
- + (o_centerPx)[1] * (matrix[1, 1] + matrix[1, 0])
- + (o_centerPx + nChan)[1] * (matrix[2, 1] + matrix[2, 0])
- + (o_centerPx + widthStep - nChan)[1] * (matrix[0, 2])
- + (o_centerPx + widthStep)[1] * (matrix[1, 2])
- + (o_centerPx + widthStep + nChan)[1] * (matrix[2, 2]);
- sum[2] = (o_centerPx - nChan)[2] * (matrix[0, 0] + matrix[0, 1])
- + (o_centerPx)[2] * (matrix[1, 1] + matrix[1, 0])
- + (o_centerPx + nChan)[2] * (matrix[2, 1] + matrix[2, 0])
- + (o_centerPx + widthStep - nChan)[2] * (matrix[0, 2])
- + (o_centerPx + widthStep)[2] * (matrix[1, 2])
- + (o_centerPx + widthStep + nChan)[2] * (matrix[2, 2]);
- w_sum[0] = Math.Round(sum[0] / matrixWeight);
- w_sum[1] = Math.Round(sum[1] / matrixWeight);
- w_sum[2] = Math.Round(sum[2] / matrixWeight);
- centerPx[0] = (byte)(w_sum[0] > 255 ? 255 : (w_sum[0] < 0) ? 0 : w_sum[0]);
- centerPx[1] = (byte)(w_sum[1] > 255 ? 255 : (w_sum[1] < 0) ? 0 : w_sum[1]);
- centerPx[2] = (byte)(w_sum[2] > 255 ? 255 : (w_sum[2] < 0) ? 0 : w_sum[2]);
- }
- // Bottom
- for (x = 1, y = h - 1; x < w - 1; x++)
- {
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- sum[0] = (o_centerPx - widthStep - nChan)[0] * (matrix[0, 0])
- + (o_centerPx - widthStep)[0] * (matrix[1, 0])
- + (o_centerPx - widthStep + nChan)[0] * (matrix[2, 0])
- + (o_centerPx - nChan)[0] * (matrix[0, 1] + matrix[0, 2])
- + (o_centerPx)[0] * (matrix[1, 1] + matrix[1, 2])
- + (o_centerPx + nChan)[0] * (matrix[2, 1] + matrix[2, 2]);
- sum[1] = (o_centerPx - widthStep - nChan)[1] * (matrix[0, 0])
- + (o_centerPx - widthStep)[1] * (matrix[1, 0])
- + (o_centerPx - widthStep + nChan)[1] * (matrix[2, 0])
- + (o_centerPx - nChan)[1] * (matrix[0, 1] + matrix[0, 2])
- + (o_centerPx)[1] * (matrix[1, 1] + matrix[1, 2])
- + (o_centerPx + nChan)[1] * (matrix[2, 1] + matrix[2, 2]);
- sum[2] = (o_centerPx - widthStep - nChan)[2] * (matrix[0, 0])
- + (o_centerPx - widthStep)[2] * (matrix[1, 0])
- + (o_centerPx - widthStep + nChan)[2] * (matrix[2, 0])
- + (o_centerPx - nChan)[2] * (matrix[0, 1] + matrix[0, 2])
- + (o_centerPx)[2] * (matrix[1, 1] + matrix[1, 2])
- + (o_centerPx + nChan)[2] * (matrix[2, 1] + matrix[2, 2]);
- w_sum[0] = Math.Round(sum[0] / matrixWeight);
- w_sum[1] = Math.Round(sum[1] / matrixWeight);
- w_sum[2] = Math.Round(sum[2] / matrixWeight);
- centerPx[0] = (byte)(w_sum[0] > 255 ? 255 : (w_sum[0] < 0) ? 0 : w_sum[0]);
- centerPx[1] = (byte)(w_sum[1] > 255 ? 255 : (w_sum[1] < 0) ? 0 : w_sum[1]);
- centerPx[2] = (byte)(w_sum[2] > 255 ? 255 : (w_sum[2] < 0) ? 0 : w_sum[2]);
- }
- // *** CORE ***
- for (y = 1; y < h - 1; y++)
- {
- for (x = 1; x < w - 1; x++)
- {
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- sum[0] = (o_centerPx - widthStep - nChan)[0] * matrix[0, 0]
- + (o_centerPx - widthStep)[0] * matrix[1, 0]
- + (o_centerPx - widthStep + nChan)[0] * matrix[2, 0]
- + (o_centerPx - nChan)[0] * matrix[0, 1]
- + (o_centerPx)[0] * matrix[1, 1]
- + (o_centerPx + nChan)[0] * matrix[2, 1]
- + (o_centerPx + widthStep - nChan)[0] * matrix[0, 2]
- + (o_centerPx + widthStep)[0] * matrix[1, 2]
- + (o_centerPx + widthStep + nChan)[0] * matrix[2, 2];
- sum[1] = (o_centerPx - widthStep - nChan)[1] * matrix[0, 0]
- + (o_centerPx - widthStep)[1] * matrix[1, 0]
- + (o_centerPx - widthStep + nChan)[1] * matrix[2, 0]
- + (o_centerPx - nChan)[1] * matrix[0, 1]
- + (o_centerPx)[1] * matrix[1, 1]
- + (o_centerPx + nChan)[1] * matrix[2, 1]
- + (o_centerPx + widthStep - nChan)[1] * matrix[0, 2]
- + (o_centerPx + widthStep)[1] * matrix[1, 2]
- + (o_centerPx + widthStep + nChan)[1] * matrix[2, 2];
- sum[2] = (o_centerPx - widthStep - nChan)[2] * matrix[0, 0]
- + (o_centerPx - widthStep)[2] * matrix[1, 0]
- + (o_centerPx - widthStep + nChan)[2] * matrix[2, 0]
- + (o_centerPx - nChan)[2] * matrix[0, 1]
- + (o_centerPx)[2] * matrix[1, 1]
- + (o_centerPx + nChan)[2] * matrix[2, 1]
- + (o_centerPx + widthStep - nChan)[2] * matrix[0, 2]
- + (o_centerPx + widthStep)[2] * matrix[1, 2]
- + (o_centerPx + widthStep + nChan)[2] * matrix[2, 2];
- w_sum[0] = Math.Round(sum[0] / matrixWeight);
- w_sum[1] = Math.Round(sum[1] / matrixWeight);
- w_sum[2] = Math.Round(sum[2] / matrixWeight);
- centerPx[0] = (byte)(w_sum[0] > 255 ? 255 : (w_sum[0] < 0) ? 0 : w_sum[0]);
- centerPx[1] = (byte)(w_sum[1] > 255 ? 255 : (w_sum[1] < 0) ? 0 : w_sum[1]);
- centerPx[2] = (byte)(w_sum[2] > 255 ? 255 : (w_sum[2] < 0) ? 0 : w_sum[2]);
- }
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Non-Uniform
- // Non Uniform Nabais -> Slower but with less errors
- public static void NonUniform(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, float[,] matrix, float matrixWeight)
- {
- unsafe
- {
- // direct access to the image memory(sequencial)
- // direcion top left -> bottom right
- MIplImage m = img.MIplImage;
- MIplImage m1 = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrref = dataPtr;
- byte* auxdataPtr = (byte*)m1.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrStatic = auxdataPtr; // Pointer de referência para o inÃcio da imagem a editar
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- int x, y, i, j;
- float blueSUM = 0, greenSUM = 0, redSUM = 0;
- dataPtr += m.widthStep + nChan;
- dataPtrStatic += m.widthStep + nChan;
- if (nChan == 3)
- {
- // dentro da imagem, fora as margens+cantos
- for (y = 1; y < height - 1; y++)
- {
- for (x = 1; x < width - 1; x++)
- {
- blueSUM = 0;
- greenSUM = 0;
- redSUM = 0;
- dataPtr = dataPtrref + y * m.widthStep + x * nChan;
- for (i = 0; i < 3; i++)
- {
- auxdataPtr = dataPtrStatic + (i - 1) * m.widthStep - nChan;
- for (j = 0; j < 3; j++)
- {
- blueSUM += matrix[i, j] * (auxdataPtr)[0];
- greenSUM += matrix[i, j] * (auxdataPtr)[1];
- redSUM += matrix[i, j] * (auxdataPtr)[2];
- auxdataPtr += nChan;
- }
- }
- blueSUM = (float)Math.Round(blueSUM / matrixWeight);
- greenSUM = (float)Math.Round(greenSUM / matrixWeight);
- redSUM = (float)Math.Round(redSUM / matrixWeight);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- dataPtrStatic += nChan;
- }
- dataPtrStatic += padding + 2 * nChan;
- }
- // última linha
- for (x = 1; x < width - 1; x++)
- {
- blueSUM = 0;
- greenSUM = 0;
- redSUM = 0;
- dataPtr = dataPtrref + y * m.widthStep + x * nChan;
- auxdataPtr = dataPtrStatic - m.widthStep - nChan;
- for (i = 0; i < 3; i++)
- {
- blueSUM += auxdataPtr[0] * matrix[i, 0];
- greenSUM += auxdataPtr[1] * matrix[i, 0];
- redSUM += auxdataPtr[2] * matrix[i, 0];
- auxdataPtr += nChan;
- }
- auxdataPtr = dataPtrStatic - nChan;
- for (i = 0; i < 3; i++)
- {
- blueSUM += auxdataPtr[0] * (matrix[i, 1] + matrix[i, 2]);
- greenSUM += auxdataPtr[1] * (matrix[i, 1] + matrix[i, 2]);
- redSUM += auxdataPtr[2] * (matrix[i, 1] + matrix[i, 2]);
- auxdataPtr += nChan;
- }
- blueSUM = (float)Math.Round(blueSUM / matrixWeight);
- greenSUM = (float)Math.Round(greenSUM / matrixWeight);
- redSUM = (float)Math.Round(redSUM / matrixWeight);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- dataPtrStatic += nChan;
- }
- dataPtr = dataPtrref + y * m.widthStep + x * nChan;
- //canto inferior direito
- {
- auxdataPtr = dataPtrStatic - m.widthStep - nChan;
- blueSUM = auxdataPtr[0] * matrix[0, 0];
- greenSUM = auxdataPtr[1] * matrix[0, 0];
- redSUM = auxdataPtr[2] * matrix[0, 0];
- auxdataPtr += nChan;
- blueSUM += auxdataPtr[0] * (matrix[0, 1] + matrix[0, 2]);
- greenSUM += auxdataPtr[1] * (matrix[0, 1] + matrix[0, 2]);
- redSUM += auxdataPtr[2] * (matrix[0, 1] + matrix[0, 2]);
- auxdataPtr = dataPtrStatic - nChan;
- blueSUM += auxdataPtr[0] * (matrix[1, 0] + matrix[2, 0]);
- greenSUM += auxdataPtr[1] * (matrix[1, 0] + matrix[2, 0]);
- redSUM += auxdataPtr[2] * (matrix[1, 0] + matrix[2, 0]);
- auxdataPtr += nChan;
- blueSUM += auxdataPtr[0] * (matrix[1, 1] + matrix[1, 2] + matrix[2, 1] + matrix[2, 2]);
- greenSUM += auxdataPtr[1] * (matrix[1, 1] + matrix[1, 2] + matrix[2, 1] + matrix[2, 2]);
- redSUM += auxdataPtr[2] * (matrix[1, 1] + matrix[1, 2] + matrix[2, 1] + matrix[2, 2]);
- blueSUM = (float)Math.Round(blueSUM / matrixWeight);
- greenSUM = (float)Math.Round(greenSUM / matrixWeight);
- redSUM = (float)Math.Round(redSUM / matrixWeight);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- dataPtrStatic -= m.widthStep;
- //última coluna
- for (y = height - 2; y > 0; y--)
- {
- blueSUM = 0;
- greenSUM = 0;
- redSUM = 0;
- dataPtr = dataPtrref + y * m.widthStep + x * nChan;
- auxdataPtr = dataPtrStatic - m.widthStep - nChan;
- for (i = 0; i < 3; i++)
- {
- blueSUM += auxdataPtr[0] * matrix[i, 0];
- greenSUM += auxdataPtr[1] * matrix[i, 0];
- redSUM += auxdataPtr[2] * matrix[i, 0];
- auxdataPtr += m.widthStep;
- }
- auxdataPtr = dataPtrStatic - m.widthStep;
- for (i = 0; i < 3; i++)
- {
- blueSUM += auxdataPtr[0] * (matrix[i, 1] + matrix[i, 2]);
- greenSUM += auxdataPtr[1] * (matrix[i, 1] + matrix[i, 2]);
- redSUM += auxdataPtr[2] * (matrix[i, 1] + matrix[i, 2]);
- auxdataPtr += m.widthStep;
- }
- blueSUM = (float)Math.Round(blueSUM / matrixWeight);
- greenSUM = (float)Math.Round(greenSUM / matrixWeight);
- redSUM = (float)Math.Round(redSUM / matrixWeight);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- dataPtrStatic -= m.widthStep;
- }
- dataPtr = dataPtrref + y * m.widthStep + x * nChan;
- //canto superior direito
- {
- auxdataPtr = dataPtrStatic - nChan;
- blueSUM = auxdataPtr[0] * (matrix[0, 0] + matrix[1, 0]);
- greenSUM = auxdataPtr[1] * (matrix[0, 0] + matrix[1, 0]);
- redSUM = auxdataPtr[2] * (matrix[0, 0] + matrix[1, 0]);
- auxdataPtr += nChan;
- blueSUM += auxdataPtr[0] * (matrix[0, 1] + matrix[0, 2] + matrix[1, 1] + matrix[1, 2]);
- greenSUM += auxdataPtr[1] * (matrix[0, 1] + matrix[0, 2] + matrix[1, 1] + matrix[1, 2]);
- redSUM += auxdataPtr[2] * (matrix[0, 1] + matrix[0, 2] + matrix[1, 1] + matrix[1, 2]);
- auxdataPtr += m.widthStep;
- blueSUM += auxdataPtr[0] * (matrix[2, 1] + matrix[2, 2]);
- greenSUM += auxdataPtr[1] * (matrix[2, 1] + matrix[2, 2]);
- redSUM += auxdataPtr[2] * (matrix[2, 1] + matrix[2, 2]);
- auxdataPtr -= nChan;
- blueSUM += auxdataPtr[0] * matrix[2, 0];
- greenSUM += auxdataPtr[1] * matrix[2, 0];
- redSUM += auxdataPtr[2] * matrix[2, 0];
- blueSUM = (float)Math.Round(blueSUM / matrixWeight);
- greenSUM = (float)Math.Round(greenSUM / matrixWeight);
- redSUM = (float)Math.Round(redSUM / matrixWeight);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- dataPtrStatic -= nChan;
- //primeira linha
- for (x = width - 2; x > 0; x--)
- {
- blueSUM = 0;
- greenSUM = 0;
- redSUM = 0;
- auxdataPtr = dataPtrStatic - nChan;
- dataPtr = dataPtrref + y * m.widthStep + x * nChan;
- for (i = 0; i < 3; i++)
- {
- blueSUM += auxdataPtr[0] * (matrix[0, i] + matrix[1, i]);
- greenSUM += auxdataPtr[1] * (matrix[0, i] + matrix[1, i]);
- redSUM += auxdataPtr[2] * (matrix[0, i] + matrix[1, i]);
- auxdataPtr += nChan;
- }
- auxdataPtr = dataPtrStatic + m.widthStep - nChan;
- for (i = 0; i < 3; i++)
- {
- blueSUM += auxdataPtr[0] * matrix[2, i];
- greenSUM += auxdataPtr[1] * matrix[2, i];
- redSUM += auxdataPtr[2] * matrix[2, i];
- auxdataPtr += nChan;
- }
- blueSUM = (float)Math.Round(blueSUM / matrixWeight);
- greenSUM = (float)Math.Round(greenSUM / matrixWeight);
- redSUM = (float)Math.Round(redSUM / matrixWeight);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- dataPtrStatic -= nChan;
- }
- dataPtr = dataPtrref + y * m.widthStep + x * nChan;
- //canto superior esquerdo
- {
- auxdataPtr = dataPtrStatic;
- blueSUM = auxdataPtr[0] * (matrix[0, 0] + matrix[0, 1] + matrix[1, 0] + matrix[1, 1]);
- greenSUM = auxdataPtr[1] * (matrix[0, 0] + matrix[0, 1] + matrix[1, 0] + matrix[1, 1]);
- redSUM = auxdataPtr[2] * (matrix[0, 0] + matrix[0, 1] + matrix[1, 0] + matrix[1, 1]);
- auxdataPtr += nChan;
- blueSUM = auxdataPtr[0] * (matrix[0, 2] + matrix[1, 2]);
- greenSUM = auxdataPtr[1] * (matrix[0, 2] + matrix[1, 2]);
- redSUM = auxdataPtr[2] * (matrix[0, 2] + matrix[1, 2]);
- auxdataPtr = dataPtrStatic + m.widthStep;
- blueSUM = auxdataPtr[0] * (matrix[2, 0] + matrix[2, 1]);
- greenSUM = auxdataPtr[1] * (matrix[2, 0] + matrix[2, 1]);
- redSUM = auxdataPtr[2] * (matrix[2, 0] + matrix[2, 1]);
- auxdataPtr += nChan;
- blueSUM = auxdataPtr[0] * matrix[2, 2];
- greenSUM = auxdataPtr[1] * matrix[2, 2];
- redSUM = auxdataPtr[2] * matrix[2, 2];
- blueSUM = (float)Math.Round(blueSUM / matrixWeight);
- greenSUM = (float)Math.Round(greenSUM / matrixWeight);
- redSUM = (float)Math.Round(redSUM / matrixWeight);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- dataPtrStatic += m.widthStep;
- //primeira coluna
- for (y = 1; y < height - 1; y++)
- {
- blueSUM = 0;
- greenSUM = 0;
- redSUM = 0;
- dataPtr = dataPtrref + y * m.widthStep + x * nChan;
- auxdataPtr = dataPtrStatic - m.widthStep;
- for (i = 0; i < 3; i++)
- {
- blueSUM += auxdataPtr[0] * (matrix[i, 0] + matrix[i, 1]);
- greenSUM += auxdataPtr[1] * (matrix[i, 0] + matrix[i, 1]);
- redSUM += auxdataPtr[2] * (matrix[i, 0] + matrix[i, 1]);
- auxdataPtr += m.widthStep;
- }
- auxdataPtr = dataPtrStatic - m.widthStep + nChan;
- for (i = 0; i < 3; i++)
- {
- blueSUM += auxdataPtr[0] * matrix[i, 2];
- greenSUM += auxdataPtr[1] * matrix[i, 2];
- redSUM += auxdataPtr[2] * matrix[i, 2];
- auxdataPtr += m.widthStep;
- }
- blueSUM = (float)Math.Round(blueSUM / matrixWeight);
- greenSUM = (float)Math.Round(greenSUM / matrixWeight);
- redSUM = (float)Math.Round(redSUM / matrixWeight);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- dataPtrStatic += m.widthStep;
- }
- dataPtr = dataPtrref + y * m.widthStep + x * nChan;
- //canto inferior esquerdo
- {
- auxdataPtr = dataPtrStatic - m.widthStep;
- blueSUM = auxdataPtr[0] * (matrix[0, 0] + matrix[0, 1]);
- greenSUM = auxdataPtr[1] * (matrix[0, 0] + matrix[0, 1]);
- redSUM = auxdataPtr[2] * (matrix[0, 0] + matrix[0, 1]);
- auxdataPtr += nChan;
- blueSUM += auxdataPtr[0] * matrix[2, 2];
- greenSUM += auxdataPtr[1] * matrix[2, 2];
- redSUM += auxdataPtr[2] * matrix[2, 2];
- auxdataPtr = dataPtrStatic;
- blueSUM += auxdataPtr[0] * (matrix[1, 0] + matrix[1, 1] + matrix[2, 0] + matrix[2, 1]);
- greenSUM += auxdataPtr[1] * (matrix[1, 0] + matrix[1, 1] + matrix[2, 0] + matrix[2, 1]);
- redSUM += auxdataPtr[2] * (matrix[1, 0] + matrix[1, 1] + matrix[2, 0] + matrix[2, 1]);
- auxdataPtr += nChan;
- blueSUM += auxdataPtr[0] * (matrix[1, 2] + matrix[2, 2]);
- greenSUM += auxdataPtr[1] * (matrix[1, 2] + matrix[2, 2]);
- redSUM += auxdataPtr[2] * (matrix[1, 2] + matrix[2, 2]);
- blueSUM = (float)Math.Round(blueSUM / matrixWeight);
- greenSUM = (float)Math.Round(greenSUM / matrixWeight);
- redSUM = (float)Math.Round(redSUM / matrixWeight);
- if (blueSUM > 255) blueSUM = 255;
- else if (blueSUM < 0) blueSUM = 0;
- if (greenSUM > 255) greenSUM = 255;
- else if (greenSUM < 0) greenSUM = 0;
- if (redSUM > 255) redSUM = 255;
- else if (redSUM < 0) redSUM = 0;
- dataPtr[0] = (byte)blueSUM;
- dataPtr[1] = (byte)greenSUM;
- dataPtr[2] = (byte)redSUM;
- }
- }
- }
- } // End of Non Uniform
- public static void Sobel(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy)
- {
- unsafe
- {
- // direct access to the image memory(sequencial)
- // direcion top left -> bottom right
- MIplImage m = img.MIplImage;
- MIplImage m1 = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* auxdataPtr = (byte*)m1.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrStatic = dataPtr; // Pointer de referência para o inÃcio da imagem a editar
- byte* a, b, c, d, e, f, g, h, i;
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- int x, y;
- if (nChan == 3)
- {
- for (y = 0; y < height; y++) //processar apenas a imagem interior sem as bordas
- {
- for (x = 0; x < width; x++)
- {
- int Sb = 0;
- int Sg = 0;
- int Sr = 0;
- dataPtr = (dataPtrStatic + y * m.widthStep + x * nChan);
- a = (auxdataPtr + (y - 1) * m.widthStep + (x - 1) * nChan);
- b = (auxdataPtr + (y - 1) * m.widthStep + x * nChan);
- c = (auxdataPtr + (y - 1) * m.widthStep + (x + 1) * nChan);
- d = (auxdataPtr + y * m.widthStep + (x - 1) * nChan);
- e = (auxdataPtr + y * m.widthStep + x * nChan);
- f = (auxdataPtr + y * m.widthStep + (x + 1) * nChan);
- g = (auxdataPtr + (y + 1) * m.widthStep + (x - 1) * nChan);
- h = (auxdataPtr + (y + 1) * m.widthStep + x * nChan);
- i = (auxdataPtr + (y + 1) * m.widthStep + (x + 1) * nChan);
- // dentro da imagem
- if ((y > 0 && y < height - 1) && (x > 0 && x < width - 1))
- {
- Sb = Math.Abs(a[0] + 2 * d[0] + g[0] - c[0] - 2 * f[0] - i[0]) + Math.Abs(g[0] + 2 * h[0] + i[0] - a[0] - 2 * b[0] - c[0]);
- Sg = Math.Abs(a[1] + 2 * d[1] + g[1] - c[1] - 2 * f[1] - i[1]) + Math.Abs(g[1] + 2 * h[1] + i[1] - a[1] - 2 * b[1] - c[1]);
- Sr = Math.Abs(a[2] + 2 * d[2] + g[2] - c[2] - 2 * f[2] - i[2]) + Math.Abs(g[2] + 2 * h[2] + i[2] - a[2] - 2 * b[2] - c[2]);
- }
- // última coluna \ cantos
- if ((x == width - 1) && (y > 0 && y < height - 1))
- {
- Sb = Math.Abs(a[0] + 2 * d[0] + g[0] - b[0] - 2 * e[0] - h[0]) + Math.Abs(g[0] + 3 * h[0] - a[0] - 3 * b[0]);
- Sg = Math.Abs(a[1] + 2 * d[1] + g[1] - b[1] - 2 * e[1] - h[1]) + Math.Abs(g[1] + 3 * h[1] - a[1] - 3 * b[1]);
- Sr = Math.Abs(a[2] + 2 * d[2] + g[2] - b[2] - 2 * e[2] - h[2]) + Math.Abs(g[2] + 3 * h[2] - a[2] - 3 * b[2]);
- }
- // última linha \ cantos
- if ((x > 0 && x < width - 1) && (y == height - 1))
- {
- Sb = Math.Abs(a[0] + 3 * d[0] - c[0] - 3 * f[0]) + Math.Abs(d[0] + 2 * e[0] + f[0] - a[0] - 2 * b[0] - c[0]);
- Sg = Math.Abs(a[1] + 3 * d[1] - c[1] - 3 * f[1]) + Math.Abs(d[1] + 2 * e[1] + f[1] - a[1] - 2 * b[1] - c[1]);
- Sr = Math.Abs(a[2] + 3 * d[2] - c[2] - 3 * f[2]) + Math.Abs(d[2] + 2 * e[2] + f[2] - a[2] - 2 * b[2] - c[2]);
- }
- // primeira coluna \ cantos
- if ((x == 0) && (y > 0 && y < height - 1))
- {
- Sb = Math.Abs(b[0] + 2 * e[0] + h[0] - c[0] - 2 * f[0] - i[0]) + Math.Abs(3 * h[0] + i[0] - 3 * b[0] - c[0]);
- Sg = Math.Abs(b[1] + 2 * e[1] + h[1] - c[1] - 2 * f[1] - i[1]) + Math.Abs(3 * h[1] + i[1] - 3 * b[1] - c[1]);
- Sr = Math.Abs(b[2] + 2 * e[2] + h[2] - c[2] - 2 * f[2] - i[2]) + Math.Abs(3 * h[2] + i[2] - 3 * b[2] - c[2]);
- }
- // primeira linha \ cantos
- if ((x > 0 && x < width - 1) && (y == 0))
- {
- Sb = Math.Abs(3 * d[0] + g[0] - 3 * f[0] - i[0]) + Math.Abs(g[0] + 2 * h[0] + i[0] - d[0] - 2 * e[0] - f[0]);
- Sg = Math.Abs(3 * d[1] + g[1] - 3 * f[1] - i[1]) + Math.Abs(g[1] + 2 * h[1] + i[1] - d[1] - 2 * e[1] - f[1]);
- Sr = Math.Abs(3 * d[2] + g[2] - 3 * f[2] - i[2]) + Math.Abs(g[2] + 2 * h[2] + i[2] - d[2] - 2 * e[2] - f[2]);
- }
- // canto sup esq
- if ((x == 0) && (y == 0))
- {
- Sb = Math.Abs(3 * e[0] + h[0] - 3 * f[0] - i[0]) + Math.Abs(3 * h[0] + i[0] - 3 * e[0] - f[0]);
- Sg = Math.Abs(3 * e[1] + h[1] - 3 * f[1] - i[1]) + Math.Abs(3 * h[1] + i[1] - 3 * e[1] - f[1]);
- Sr = Math.Abs(3 * e[2] + h[2] - 3 * f[2] - i[2]) + Math.Abs(3 * h[2] + i[2] - 3 * e[2] - f[2]);
- }
- // canto sup dir
- if ((x == width - 1) && (y == 0))
- {
- Sb = Math.Abs(3 * d[0] + g[0] - 3 * e[0] - h[0]) + Math.Abs(g[0] + 3 * h[0] - d[0] - 3 * e[0]);
- Sg = Math.Abs(3 * d[1] + g[1] - 3 * e[1] - h[1]) + Math.Abs(g[1] + 3 * h[1] - d[1] - 3 * e[1]);
- Sr = Math.Abs(3 * d[2] + g[2] - 3 * e[2] - h[2]) + Math.Abs(g[2] + 3 * h[2] - d[2] - 3 * e[2]);
- }
- // canto inf esq
- if ((x == 0) && (y == height - 1))
- {
- Sb = Math.Abs(b[0] + 3 * e[0] - c[0] - 3 * f[0]) + Math.Abs(3 * e[0] + f[0] - 3 * b[0] - c[0]);
- Sg = Math.Abs(b[1] + 3 * e[1] - c[1] - 3 * f[1]) + Math.Abs(3 * e[1] + f[1] - 3 * b[1] - c[1]);
- Sr = Math.Abs(b[2] + 3 * e[2] - c[2] - 3 * f[2]) + Math.Abs(3 * e[2] + f[2] - 3 * b[2] - c[2]);
- }
- // canto inf dir
- if ((x == width - 1) && (y == height - 1))
- {
- Sb = Math.Abs(a[0] + 3 * d[0] - b[0] - 3 * e[0]) + Math.Abs(d[0] + 3 * e[0] - a[0] - 3 * b[0]);
- Sg = Math.Abs(a[1] + 3 * d[1] - b[1] - 3 * e[1]) + Math.Abs(d[1] + 3 * e[1] - a[1] - 3 * b[1]);
- Sr = Math.Abs(a[2] + 3 * d[2] - b[2] - 3 * e[2]) + Math.Abs(d[2] + 3 * e[2] - a[2] - 3 * b[2]);
- }
- if (Sb > 255) Sb = 255;
- else if (Sb < 0) Sb = 0;
- if (Sg > 255) Sg = 255;
- else if (Sg < 0) Sg = 0;
- if (Sr > 255) Sr = 255;
- else if (Sr < 0) Sr = 0;
- dataPtr[0] = (byte)Sb;
- dataPtr[1] = (byte)Sg;
- dataPtr[2] = (byte)Sr;
- }
- }
- }
- }
- } // End of Sobel
- public static void Diferentiation(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy)
- {
- unsafe
- {
- MIplImage m = imgCopy.MIplImage;
- MIplImage d = img.MIplImage;
- byte* dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- byte* centerPx, o_centerPx;
- int w = img.Width;
- int h = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int x, y;
- double[] result = new double[3];
- if (nChan == 3) // image in RGB
- {
- // Left Border
- x = w - 1;
- for (y = 0; y < h - 1; y++)
- {
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- result[0] = (Math.Abs((int)(o_centerPx)[0] - (o_centerPx)[0]) + Math.Abs((int)(o_centerPx)[0] - (o_centerPx + widthStep)[0]));
- result[1] = (Math.Abs((int)(o_centerPx)[1] - (o_centerPx)[1]) + Math.Abs((int)(o_centerPx)[1] - (o_centerPx + widthStep)[1]));
- result[2] = (Math.Abs((int)(o_centerPx)[2] - (o_centerPx)[2]) + Math.Abs((int)(o_centerPx)[2] - (o_centerPx + widthStep)[2]));
- centerPx[0] = (byte)(result[0] > 255 ? 255 : Math.Round(result[0]));
- centerPx[1] = (byte)(result[1] > 255 ? 255 : Math.Round(result[1]));
- centerPx[2] = (byte)(result[2] > 255 ? 255 : Math.Round(result[2]));
- }
- // Bottom Border
- y = h - 1;
- for (x = 0; x < w - 1; x++)
- {
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- result[0] = (Math.Abs((int)(o_centerPx)[0] - (o_centerPx + nChan)[0]) + Math.Abs((int)(o_centerPx)[0] - (o_centerPx)[0]));
- result[1] = (Math.Abs((int)(o_centerPx)[1] - (o_centerPx + nChan)[1]) + Math.Abs((int)(o_centerPx)[1] - (o_centerPx)[1]));
- result[2] = (Math.Abs((int)(o_centerPx)[2] - (o_centerPx + nChan)[2]) + Math.Abs((int)(o_centerPx)[2] - (o_centerPx)[2]));
- centerPx[0] = (byte)(result[0] > 255 ? 255 : Math.Round(result[0]));
- centerPx[1] = (byte)(result[1] > 255 ? 255 : Math.Round(result[1]));
- centerPx[2] = (byte)(result[2] > 255 ? 255 : Math.Round(result[2]));
- }
- // Bottom Right Corner
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- x = w - 1; y = h - 1;
- centerPx[0] = (byte)0;
- centerPx[1] = (byte)0;
- centerPx[2] = (byte)0;
- // *** CORE ***
- for (y = 0; y < h - 1; y++)
- {
- for (x = 0; x < w - 1; x++)
- {
- o_centerPx = dataPtr_org + y * widthStep + x * nChan;
- centerPx = dataPtr + y * widthStep + x * nChan;
- result[0] = (Math.Abs((int)(o_centerPx)[0] - (o_centerPx + nChan)[0]) + Math.Abs((int)(o_centerPx)[0] - (o_centerPx + widthStep)[0]));
- result[1] = (Math.Abs((int)(o_centerPx)[1] - (o_centerPx + nChan)[1]) + Math.Abs((int)(o_centerPx)[1] - (o_centerPx + widthStep)[1]));
- result[2] = (Math.Abs((int)(o_centerPx)[2] - (o_centerPx + nChan)[2]) + Math.Abs((int)(o_centerPx)[2] - (o_centerPx + widthStep)[2]));
- centerPx[0] = (byte)(result[0] > 255 ? 255 : Math.Round(result[0]));
- centerPx[1] = (byte)(result[1] > 255 ? 255 : Math.Round(result[1]));
- centerPx[2] = (byte)(result[2] > 255 ? 255 : Math.Round(result[2]));
- }
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Diferentiation
- public static void Median(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy)
- {
- unsafe
- {
- MIplImage m = imgCopy.MIplImage;
- MIplImage d = img.MIplImage;
- img.SmoothMedian(3).CopyTo(img);
- } // End of Unsafe
- } // End of Median
- public static int[] Histogram_Gray(Emgu.CV.Image<Bgr, byte> img)
- {
- unsafe
- {
- MIplImage d = img.MIplImage;
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- int w = img.Width;
- int h = img.Height;
- int nChan = d.nChannels; // number of channels - 3
- int widthStep = d.widthStep;
- int padding = widthStep - nChan * w;
- int x, y;
- byte gray;
- int[] result = new int[256];
- if (nChan == 1)
- {
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- result[dataPtr[0]]++;
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 1
- else if (nChan == 3)
- {
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- gray = (byte)Math.Round((dataPtr[0] + dataPtr[1] + dataPtr[2]) / 3.0);
- result[dataPtr[gray]]++;
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- return result;
- } // End of Unsafe
- } // End of Histogram_Gray
- public static int[,] Histogram_RGB(Emgu.CV.Image<Bgr, byte> img)
- {
- unsafe
- {
- MIplImage d = img.MIplImage;
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- int w = img.Width;
- int h = img.Height;
- int nChan = d.nChannels; // number of channels - 3
- int widthStep = d.widthStep;
- int padding = widthStep - nChan * w;
- int x, y;
- int[,] result = new int[3, 256];
- if (nChan == 3) // image in RGB
- {
- // *** CORE ***
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- result[0, dataPtr[0]]++;
- result[1, dataPtr[1]]++;
- result[2, dataPtr[2]]++;
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- return result;
- } // End of Unsafe
- } // End of Histogram_RGB
- public static int[,] Histogram_All(Emgu.CV.Image<Bgr, byte> img)
- {
- unsafe
- {
- MIplImage d = img.MIplImage;
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- int w = img.Width;
- int h = img.Height;
- int nChan = d.nChannels; // number of channels - 3
- int widthStep = d.widthStep;
- int padding = widthStep - nChan * w;
- int x, y;
- byte gray;
- int[,] result = new int[4, 256];
- if (nChan == 3) // image in RGB
- {
- // *** CORE ***
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- gray = (byte)Math.Round((dataPtr[0] + dataPtr[1] + dataPtr[2]) / 3.0);
- result[0, dataPtr[0]]++; //R
- result[1, dataPtr[1]]++; //G
- result[2, dataPtr[2]]++; //B
- result[3, dataPtr[gray]]++; //B
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- return result;
- } // End of Unsafe
- } // End of Histogram_All
- public static void ConvertToBW(Emgu.CV.Image<Bgr, byte> img, int threshold)
- {
- unsafe
- {
- // direct access to the image memory(sequencial)
- // direcion top left -> bottom right
- MIplImage m = img.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- if (nChan == 3) // image in RGB
- {
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- if (Math.Round(((float)dataPtr[0] + (float)dataPtr[1] + (float)dataPtr[2]) / 3) <= threshold)
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- }
- else
- {
- dataPtr[0] = 255;
- dataPtr[1] = 255;
- dataPtr[2] = 255;
- }
- // advance the pointer to the next pixel
- dataPtr += nChan;
- }
- //at the end of the line advance the pointer by the aligment bytes (padding)
- dataPtr += padding;
- }
- }
- }
- } // End of ConvertToBW
- public static void ConvertToBW_Otsu(Emgu.CV.Image<Bgr, byte> img)
- {
- unsafe
- {
- // direct access to the image memory(sequencial)
- // direcion top left -> bottom right
- MIplImage m = img.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte blue, green, red;
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- int gray;
- int nPixels = width * height;
- int t, threshold = 0;
- float[] pixels = new float[256];
- float[] probPixel = new float[256];
- float q1, q2;
- float u1, u2;
- float varInterClass = 0;
- float varInterClassAux;
- if (nChan == 3) // image in RGB
- {
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- blue = dataPtr[0];
- green = dataPtr[1];
- red = dataPtr[2];
- // convert to gray
- gray = (int)Math.Round(((float)(blue + green + red) / 3));
- pixels[gray] += 1;
- // advance the pointer to the next pixel
- dataPtr += nChan;
- }
- }
- for (int i = 0; i < 256; i++)
- {
- probPixel[i] = pixels[i] / nPixels;
- }
- for (t = 0; t < 256; t++)
- {
- q1 = 0; q2 = 0;
- u1 = 0; u2 = 0;
- varInterClassAux = 0;
- for (int i = 0; i <= t; i++)
- {
- q1 += probPixel[i];
- }
- for (int i = 0; i <= t; i++)
- {
- u1 += i * probPixel[i];
- }
- u1 = u1 / q1;
- for (int j = t + 1; j < 256; j++)
- {
- q2 += probPixel[j];
- }
- for (int j = t + 1; j < 256; j++)
- {
- u2 += j * probPixel[j];
- }
- u2 = u2 / q2;
- varInterClassAux = q1 * q2 * (u1 - u2) * (u1 - u2);
- if (varInterClassAux >= varInterClass)
- {
- varInterClass = varInterClassAux;
- threshold = t;
- }
- }
- ConvertToBW(img, threshold);
- }
- }
- } // End of ConvertToBW_Otsu
- // *** Aux Puzzle Functions ***
- public static void Translation_xy(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, double[] posic_inicial, double[] posic_final, byte[] bckgrd)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- MIplImage c = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrCopy = (byte*)c.imageData.ToPointer(); // Pointer to the image
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- byte blue, green, red;
- int x, y;
- int dx, dy;
- dx = (int)(posic_final[0] - posic_inicial[0]);
- dy = (int)(posic_final[1] - posic_inicial[1]);
- if (nChan == 3)
- {
- for (y = (int)posic_inicial[1]; y <= posic_inicial[3]; y++)
- {
- for (x = (int)posic_inicial[0]; x <= posic_inicial[2]; x++)
- {
- blue = (byte)(dataPtrCopy + y * widthStep + x * nChan)[0];
- green = (byte)(dataPtrCopy + y * widthStep + x * nChan)[1];
- red = (byte)(dataPtrCopy + y * widthStep + x * nChan)[2];
- // Fill with background where the piece used to be
- if (dx < 0 && dy < 0)
- {
- if (y >= posic_inicial[1] + dy || x >= posic_inicial[0] + dy)
- {
- // = background colour
- (dataPtrCopy + y * widthStep + x * nChan)[0] = bckgrd[0];
- (dataPtrCopy + y * widthStep + x * nChan)[1] = bckgrd[1];
- (dataPtrCopy + y * widthStep + x * nChan)[2] = bckgrd[2];
- }
- }
- else if (dx < 0 && dy >= 0)
- {
- if (y < posic_inicial[1] + dy || x >= posic_inicial[2] + dx)
- {
- // = background colour
- (dataPtrCopy + y * widthStep + x * nChan)[0] = bckgrd[0];
- (dataPtrCopy + y * widthStep + x * nChan)[1] = bckgrd[1];
- (dataPtrCopy + y * widthStep + x * nChan)[2] = bckgrd[2];
- }
- }
- else if (dx >= 0 && dy < 0)
- {
- if (y >= posic_inicial[3] + dy || x < posic_inicial[0] + dx)
- {
- // = background colour
- (dataPtrCopy + y * widthStep + x * nChan)[0] = bckgrd[0];
- (dataPtrCopy + y * widthStep + x * nChan)[1] = bckgrd[1];
- (dataPtrCopy + y * widthStep + x * nChan)[2] = bckgrd[2];
- }
- }
- else if (dx >= 0 && dy >= 0)
- {
- if (y < posic_inicial[1] + dy || x < posic_inicial[0] + dx)
- {
- // = background colour
- (dataPtrCopy + y * widthStep + x * nChan)[0] = bckgrd[0];
- (dataPtrCopy + y * widthStep + x * nChan)[1] = bckgrd[1];
- (dataPtrCopy + y * widthStep + x * nChan)[2] = bckgrd[2];
- }
- }
- if (x + dx >= 0 && y + dy >= 0 && x + dx < width && y + dy < height)
- {
- (dataPtr + (y + dy) * widthStep + (x + dx) * nChan)[0] = blue;
- (dataPtr + (y + dy) * widthStep + (x + dx) * nChan)[1] = green;
- (dataPtr + (y + dy) * widthStep + (x + dx) * nChan)[2] = red;
- }
- }
- }
- }
- }
- } // End of Translation XY
- public static void Translation__xy_NoReplace(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, double[] posic_inicial, double[] posic_final)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- MIplImage c = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrCopy = (byte*)c.imageData.ToPointer(); // Pointer to the image
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- byte blue, green, red;
- int x, y;
- int dx, dy;
- dx = (int)(posic_final[0] - posic_inicial[0]);
- dy = (int)(posic_final[1] - posic_inicial[1]);
- if (nChan == 3)
- {
- for (y = (int)posic_inicial[1]; y <= posic_inicial[3]; y++)
- {
- for (x = (int)posic_inicial[0]; x <= posic_inicial[2]; x++)
- {
- blue = (byte)(dataPtrCopy + y * widthStep + x * nChan)[0];
- green = (byte)(dataPtrCopy + y * widthStep + x * nChan)[1];
- red = (byte)(dataPtrCopy + y * widthStep + x * nChan)[2];
- if (x + dx >= 0
- && y + dy >= 0
- && x + dx < width
- && y + dy < height)
- {
- (dataPtr + (y + dy) * widthStep + (x + dx) * nChan)[0] = blue;
- (dataPtr + (y + dy) * widthStep + (x + dx) * nChan)[1] = green;
- (dataPtr + (y + dy) * widthStep + (x + dx) * nChan)[2] = red;
- }
- }
- }
- }
- }
- } // End of Translation XY No Replace
- static public void RotatePieces(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, int[,] labels, Dictionary<int, double[]> obj_list)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- MIplImage mc = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* auxdataPtr = (byte*)mc.imageData.ToPointer(); // Pointer to the image
- byte* px;
- byte* pxCopy;
- byte* a, b, c, d;
- int x, y;
- int widthStep = m.widthStep;
- int nChan = m.nChannels; // number of channels - 3
- double[] sqr;
- Dictionary<int, double[]>.Enumerator objlist_enum = obj_list.GetEnumerator();
- while (objlist_enum.MoveNext())
- {
- sqr = objlist_enum.Current.Value;
- if (sqr[4] != 0)
- {
- // Must rotate image
- sqr[4] = (Math.PI * (int)sqr[4]) / 180;
- double sin = Math.Sin(sqr[4]);
- double cos = Math.Cos(sqr[4]);
- double w = sqr[2] + sqr[0] + 1;
- double h = sqr[3] + sqr[1] + 1;
- double xc = (-((w) / 2) * cos) - ((h / 2) * sin) + (w / 2);
- double yc = ((w / 2) * sin) - ((h / 2) * cos) + (h / 2);
- double xo, yo;
- double j, k;
- int xr, yr;
- double blueS, greenS, redS;
- double blueI, greenI, redI;
- // Get new corners for rotated piece
- double[] corners = new double[4] { sqr[0], sqr[1], sqr[2], sqr[3] };
- for (y = (int)sqr[1]; y <= sqr[3]; y++)
- {
- for (x = (int)sqr[0]; x <= sqr[2]; x++)
- {
- // Reset the label values
- labels[y, x] = int.MaxValue;
- xo = xc + x * cos + y * sin;
- yo = yc - x * sin + y * cos;
- j = xo % 1;
- k = yo % 1;
- xr = (int)(xo - j);
- yr = (int)(yo - k);
- px = (dataPtr + y * m.widthStep + x * nChan);
- pxCopy = (auxdataPtr + yr * widthStep + xr * nChan);
- if (xr < sqr[0] - 1 || xr > sqr[2] || yr < sqr[1] - 1 || yr > sqr[3])
- {
- px[0] = dataPtr[0];
- px[1] = dataPtr[1];
- px[2] = dataPtr[2];
- }
- else if ((xr >= 0 && xr < w) && (yr >= 0 && yr < h))
- {
- // Update the new coordinates with the same label
- labels[y, x] = objlist_enum.Current.Key;
- a = (pxCopy);
- b = (pxCopy + nChan);
- c = (pxCopy + widthStep);
- d = (pxCopy + nChan + widthStep);
- // Bx+j,y = (1 - j) * Bx,y + j * Bx+1,y
- blueS = (1 - j) * a[0] + j * b[0];
- greenS = (1 - j) * a[1] + j * b[1];
- redS = (1 - j) * a[2] + j * b[2];
- // Bx+j,y+1 = (1 - j) * Bx,y+1 + j * Bx+1,y+1
- blueI = (1 - j) * c[0] + j * d[0];
- greenI = (1 - j) * c[1] + j * d[1];
- redI = (1 - j) * c[2] + j * d[2];
- // Bx+j,y+k = (1 - k) * Bx+j,y + k * Bx+j,y+1
- px[0] = (byte)(Math.Round((1 - k) * blueS + k * blueI));
- px[1] = (byte)(Math.Round((1 - k) * greenS + k * greenI));
- px[2] = (byte)(Math.Round((1 - k) * redS + k * redI));
- }
- else
- {
- px[0] = 0;
- px[1] = 0;
- px[2] = 0;
- }
- } // End of For X
- } // End of For Y
- // Reattribute labels and define new corner values
- bool FIRST_OCCURENCE = false;
- for (y = (int)sqr[1]; y <= sqr[3]; y++)
- {
- for (x = (int)sqr[0]; x <= sqr[2]; x++)
- {
- px = (dataPtr + y * m.widthStep + x * nChan);
- if (px[0] != dataPtr[0] && px[1] != dataPtr[1] && px[2] != dataPtr[2])
- {
- labels[y, x] = objlist_enum.Current.Key;
- if (!FIRST_OCCURENCE)
- {
- FIRST_OCCURENCE = true;
- corners[0] = x;
- corners[1] = y;
- corners[2] = x;
- corners[3] = y;
- }
- else
- {
- if (x < corners[0])
- corners[0] = x;
- if (y < corners[1])
- corners[1] = y;
- if (x > corners[2])
- corners[2] = x;
- if (y > corners[3])
- corners[3] = y;
- }
- }
- }
- }
- // Remove the border of the piece, because it's the leftover from the bilinearization
- // Set the new values for rotated piece
- objlist_enum.Current.Value[0] = ++corners[0];
- objlist_enum.Current.Value[1] = ++corners[1];
- objlist_enum.Current.Value[2] = --corners[2];
- objlist_enum.Current.Value[3] = --corners[3];
- } // End of If Sqr4 != 4
- } // End of Obj_List Enum
- } // End of Unsafe
- } // End of Rotate Pieces
- public static double[] Scale_Piece(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, double[] sqr, double sF, byte[] bckgrnd)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- MIplImage m1 = imgCopy.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* dataPtrCopy = (byte*)m1.imageData.ToPointer(); // Pointer to the image
- byte* px, pxCopy;
- byte* a, b, c, d;
- int width = img.Width;
- int height = img.Height;
- int nChan = m.nChannels; // number of channels - 3
- int widthStep = m.widthStep;
- int padding = m.widthStep - m.nChannels * m.width; // alinhament bytes (padding)
- int x, y, w, h;
- double xo, yo;
- double j, k;
- double blueS, greenS, redS;
- double blueI, greenI, redI;
- int xr, yr; // reduzido ?
- w = (int)sqr[2] - (int)sqr[0] + 1;
- h = (int)sqr[3] - (int)sqr[1] + 1;
- if (sF > 1)
- {
- // Because we scale the piece according to it's relative (0, 0) position,
- // the coordinates of the top left corner don't change.
- sqr[2] = Math.Round(sqr[2] + (sF - 1) * w);
- sqr[3] = Math.Round(sqr[3] + (sF - 1) * h);
- }
- if (nChan == 3)
- {
- for (y = (int)sqr[1]; y <= sqr[3]; y++)
- {
- for (x = (int)sqr[0]; x <= sqr[2]; x++)
- {
- // CANTO SUPERIOR ESQUERDO DA PEÇA
- xo = x / sF + (sqr[0] - sqr[0] / sF);
- yo = y / sF + (sqr[1] - sqr[1] / sF);
- j = xo % 1; // parte decimal da coordenada em x
- k = yo % 1; // parte decimal da coordenada em y
- xr = (int)(xo - j);
- yr = (int)(yo - k);
- px = (dataPtr + y * widthStep + x * nChan);
- // calcula endereço do pixel no ponto (x,y)
- if ((xo >= 0 && xo < width) && (yo >= 0 && yo <= height))
- {
- if (xo == width - 1)
- xr--; // para não passar da imagem quando (xr + 1)
- if (yo == height - 1)
- yr--; // para não passar da imagem quando (yr + 1)
- pxCopy = (dataPtrCopy + yr * m.widthStep + xr * nChan);
- a = (pxCopy);
- b = (pxCopy + nChan);
- c = (pxCopy + widthStep);
- d = (pxCopy + nChan + widthStep);
- if (x == sqr[2])
- {
- b = (pxCopy);
- d = (pxCopy + widthStep);
- }
- if (y == sqr[3])
- {
- c = (pxCopy);
- d = (pxCopy + nChan);
- }
- if (x == sqr[2] && y == sqr[3]) d = (pxCopy);
- // Bx+j,y = (1 - j) * Bx,y + j * Bx+1,y
- blueS = (1 - j) * a[0] + j * b[0];
- greenS = (1 - j) * a[1] + j * b[1];
- redS = (1 - j) * a[2] + j * b[2];
- // Bx+j,y+1 = (1 - j) * Bx,y+1 + j * Bx+1,y+1
- blueI = (1 - j) * c[0] + j * d[0];
- greenI = (1 - j) * c[1] + j * d[1];
- redI = (1 - j) * c[2] + j * d[2];
- // Bx+j,y+k = (1 - k) * Bx+j,y + k * Bx+j,y+1
- px[0] = (byte)(Math.Round((1 - k) * blueS + k * blueI));
- px[1] = (byte)(Math.Round((1 - k) * greenS + k * greenI));
- px[2] = (byte)(Math.Round((1 - k) * redS + k * redI));
- }
- else
- {
- px[0] = 0;
- px[1] = 0;
- px[2] = 0;
- }
- }
- }
- // Copy resulted image from imgFinal back to imgCopy
- for (y = (int)sqr[1]; y <= sqr[3]; y++)
- {
- for (x = (int)sqr[0]; x <= sqr[2]; x++)
- {
- px = (dataPtr + y * widthStep + x * nChan);
- pxCopy = (dataPtrCopy + y * m.widthStep + x * nChan);
- pxCopy[0] = px[0];
- pxCopy[1] = px[1];
- pxCopy[2] = px[2];
- }
- }
- // Clean the image from imgFinal
- ClearTrace(img, sqr, bckgrnd);
- } // End of nChan = 3
- return sqr;
- } // End of Unsafe
- } // End of Scale Piece Bilinear
- public static void ClearTrace(Image<Bgr, byte> img, double[] sqr, byte[] bckgrd)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- byte* px;
- int widthStep = m.widthStep;
- int nChan = m.nChannels; // number of channels - 3
- int x, y;
- if (nChan == 3)
- {
- for (y = (int)sqr[1]; y <= sqr[3]; y++)
- {
- for (x = (int)sqr[0]; x <= sqr[2]; x++)
- {
- px = (dataPtr + y * widthStep + x * nChan);
- px[0] = bckgrd[0];
- px[1] = bckgrd[1];
- px[2] = bckgrd[2];
- } // End of For X
- } // End of For Y
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Clear Trace
- public static void ClearImage(Image<Bgr, byte> img)
- {
- unsafe
- {
- MIplImage m = img.MIplImage;
- byte* dataPtr = (byte*)m.imageData.ToPointer(); // Pointer to the image
- int width = img.Width;
- int height = img.Height;
- int widthStep = m.widthStep;
- int nChan = m.nChannels; // number of channels - 3
- int padding = widthStep - nChan * width;
- int x, y;
- byte[] bckgrnd = new byte[3] { dataPtr[0], dataPtr[1], dataPtr[2] };
- if (nChan == 3) // image in RGB
- {
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- dataPtr[0] = bckgrnd[0];
- dataPtr[1] = bckgrnd[1];
- dataPtr[2] = bckgrnd[2];
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of ClearImage
- // To Do - Remove one iteration
- public static int[,] Classification(Image<Bgr, byte> img, bool adj8, bool show_result)
- {
- unsafe
- {
- Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
- Trace.AutoFlush = true;
- Trace.Indent();
- MIplImage d = img.MIplImage;
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- int w = img.Width;
- int h = img.Height;
- int nChan = d.nChannels;
- int widthStep = d.widthStep;
- int padding = widthStep - nChan * w;
- int x, y;
- int label_index = 0;
- int[,] labels = new int[h, w];
- int px_label, neig_smaller_label;
- int[] neighbors = new int[4];
- Dictionary<int, int> conflicts_list = new Dictionary<int, int>();
- // Convert Background (0,0) to Gray
- byte gray, bckgrnd_gray;
- // Classification
- if (nChan == 3)
- {
- bckgrnd_gray = (byte)Math.Round((dataPtr[0] + dataPtr[1] + dataPtr[2]) / 3.0); // Inner Testing Background px_label
- // Label Array Init
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- // Convert Selection to Gray
- gray = (byte)Math.Round((dataPtr[0] + dataPtr[1] + dataPtr[2]) / 3.0);
- // Label
- if (gray == bckgrnd_gray)
- labels[y, x] = int.MaxValue;
- else
- labels[y, x] = ++label_index;
- dataPtr += nChan;
- }
- dataPtr += padding;
- } // End of Labeling Array
- // Core
- for (y = 1; y < h - 1; y++)
- {
- for (x = 1; x < w - 1; x++)
- {
- px_label = labels[y, x]; // Get Label
- if (px_label != int.MaxValue)
- {
- // Not background (represented by MaxValueInt)
- neig_smaller_label = px_label;
- if (adj8)
- neighbors = new int[] { labels[y - 1, x - 1], labels[y - 1, x], labels[y - 1, x + 1], labels[y, x - 1], labels[y, x + 1], labels[y + 1, x - 1], labels[y + 1, x], labels[y + 1, x + 1] }; // Form 8_adj neighborhood
- else
- neighbors = new int[] { labels[y, x - 1], labels[y, x + 1], labels[y + 1, x], labels[y - 1, x] }; // Form 4_adj neighborhood
- // Run Neighborhood || Aux Value represents the actual smallest px_label that can exist in the neighborhood, a px_label of 0 only exists on the first run of if no neighbor is smaller
- for (int j = 0; j < neighbors.Length; j++)
- {
- if (neighbors[j] != int.MaxValue && neighbors[j] < px_label)
- {
- // Neighbor is not background and is smaller than current label
- if (neig_smaller_label == px_label)
- {
- // No Conflict - Aux gets the px_label of the neighbor (that is smaller)
- neig_smaller_label = neighbors[j];
- }
- else if (neig_smaller_label != neighbors[j])
- {
- // Smaller label exists | There is a conflict | However, the neighbor label must be different than the current lowest.
- // To create conflict, biggest value goes in the first position followed by the smallest
- int key, value;
- if (neig_smaller_label > neighbors[j])
- {
- key = neig_smaller_label;
- value = neighbors[j];
- }
- else
- {
- key = neighbors[j];
- value = neig_smaller_label;
- }
- if (!conflicts_list.TryGetValue(key, out int aux_value))
- conflicts_list.Add(key, value); // Add conflict to list
- else
- {
- // Conflict already exists - Create indirect conflict **** VERIFY IF IT EVER HAPPENS
- if (aux_value > value && !conflicts_list.ContainsKey(aux_value))
- conflicts_list.Add(aux_value, value);
- else if (value > aux_value && !conflicts_list.ContainsKey(value))
- conflicts_list.Add(value, aux_value);
- }
- neig_smaller_label = value; // neig_smaller_label now has the smallest label again.
- }
- }
- } // End of Neighborhood
- labels[y, x] = neig_smaller_label; // Assign to label
- } // End of Label != Backgrond
- }
- } // End of Core
- // Resolve Conflicts
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- while (conflicts_list.TryGetValue(labels[y, x], out px_label))
- labels[y, x] = px_label; // Replace Conflicts
- }
- } // End of Resolve Conflicts
- // Debug
- if (show_result)
- {
- dataPtr = (byte*)d.imageData.ToPointer();
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- px_label = labels[y, x];
- if (px_label == int.MaxValue)
- {
- // Background
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- }
- else
- {
- // Label
- if ((byte)px_label < 150)
- px_label += 100;
- dataPtr[0] = (byte)px_label;
- dataPtr[1] = (byte)px_label;
- dataPtr[2] = (byte)px_label;
- }
- dataPtr += nChan;
- }
- dataPtr += padding;
- }
- } // End of Show Result
- return labels;
- } // End of nChan = 3
- return null;
- } // End of Unsafe
- } // End of Classification_8adj
- static public Dictionary<int, double[]> FindCorners(int[,] labels, int w, int h)
- {
- unsafe
- {
- int x, y;
- int label;
- Dictionary<int, double[]> obj_list = new Dictionary<int, double[]>();
- double[] corner;
- for (y = 0; y < h; y++)
- {
- for (x = 0; x < w; x++)
- {
- label = labels[y, x];
- if (label != int.MaxValue)
- {
- if (obj_list.TryGetValue(label, out corner))
- {
- // Label found | Change square bigger/small x,y
- if (x < corner[0])
- corner[0] = x;
- if (y < corner[1])
- corner[1] = y;
- if (x > corner[2])
- corner[2] = x;
- if (y > corner[3])
- corner[3] = y;
- obj_list.Remove(label);
- obj_list.Add(label, corner);
- }
- else
- {
- // New Label | Add new Labeled Square to list
- corner = new double[6];
- corner[0] = x; // Top Left X | minor_x
- corner[1] = y; // Top Left Y | minor_y
- corner[2] = x; // Bottom Right X | bigger_x
- corner[3] = y; // Bottom Right Y | bigger_y
- corner[5] = 0; // In the original
- obj_list.Add(label, corner);
- }
- } // End of Label != int.MaxValue
- }
- }
- // Verify if squares are rotated
- Dictionary<int, double[]>.Enumerator obj_enum = obj_list.GetEnumerator();
- while (obj_enum.MoveNext())
- {
- x = (int)obj_enum.Current.Value[0];
- y = (int)obj_enum.Current.Value[1];
- label = labels[(int)y, (int)x];
- if (label == int.MaxValue)
- {
- int x_right = x;
- int y_below = y;
- // Y
- do
- {
- y_below++;
- } while (labels[(int)y_below, (int)x] == int.MaxValue);
- // X
- do
- {
- x_right++;
- } while (labels[(int)y, (int)x_right] == int.MaxValue);
- // Object is rotate, must infer rotation angle
- double o = y_below - y;
- double a = x_right - x;
- obj_enum.Current.Value[4] = (Math.Atan(o / a) * 180) / Math.PI;
- }
- else
- {
- // Object is not rotated, angle is zero
- obj_enum.Current.Value[4] = 0;
- }
- }
- return obj_list;
- } // End of Unsafe
- } // End of FindCorners
- static public Dictionary<Tuple<int, int>, int[]> EdgeComparison(Image<Bgr, byte> img, Image<Bgr, byte> imgFinal, Dictionary<int, double[]> obj_list, Boolean runDiffSizeEdges)
- {
- unsafe
- {
- MIplImage copy = img.MIplImage;
- MIplImage final = imgFinal.MIplImage;
- byte* dataPtr = (byte*)copy.imageData.ToPointer(); // Pointer to the Image
- byte* dataPtrFinal = (byte*)final.imageData.ToPointer(); // Pointer to the Image
- byte* img1Ptr, img2Ptr;
- byte* px, px_copy;
- int nChan = copy.nChannels;
- int widthStep = copy.widthStep;
- List<int> keyList = new List<int>(obj_list.Keys);
- int[] labelArray = new int[keyList.Count];
- Dictionary<Tuple<int, int>, int[]> piece_resemblance = new Dictionary<Tuple<int, int>, int[]>();
- Tuple<int, int> piecesCombination; // key piece_resemblance
- //int[] edgeDiff = new int[4]; // value piece_resemblance
- double edgeSize1, edgeSize2;
- double n, m, u, v;
- int i, j, t;
- int gray1, gray2;
- i = 0;
- // Pass label values from list to array
- foreach (int keyIterator in keyList)
- {
- labelArray[i] = keyIterator;
- i++;
- }
- // ------------------------------------------------------------------------
- // Total combinations : n * (n - 1) / 2
- // Notes: Ensures i != j always (a piece is never compared with itself);
- // j is always ahead of i;
- // The last object is never analysed by i;
- // ------------------------------------------------------------------------
- for (i = 0; i < labelArray.Length - 1; i++)
- {
- for (j = i + 1; j < labelArray.Length; j++)
- {
- // Because the labels are always in increasing order, labelArray[i] < labelArray[j] always happens. But just in case...
- if (labelArray[i] < labelArray[j])
- piecesCombination = new Tuple<int, int>(labelArray[i], labelArray[j]);
- else
- piecesCombination = new Tuple<int, int>(labelArray[j], labelArray[i]);
- // Get the corners for each object
- obj_list.TryGetValue(piecesCombination.Item1, out double[] corners1);
- obj_list.TryGetValue(piecesCombination.Item2, out double[] corners2);
- // Edge difference created here to generate a 'new' variable. Otherwise, it would overwrite the other edges.
- // Init with max contrast
- // [0] Left edge; [1] Right edge; [2] Top edge; [3] Bottom edge;
- int[] edgeDiff = new int[4] { 255, 255, 255, 255 }; // value piece_resemblance
- //img1Ptr = (corners1[5] == 1) ? dataPtrFinal : dataPtr;
- //img2Ptr = (corners2[5] == 1) ? dataPtrFinal : dataPtr;
- // ---------------------------------------------------------- Left & Right edges
- // Left edges
- edgeSize1 = corners1[3] - corners1[1] + 1;
- edgeSize2 = corners2[3] - corners2[1] + 1;
- if (edgeSize1 == edgeSize2) // Level2. Length of edge must be the same
- {
- for (t = 0; t < edgeSize1; t++) // Iterate along the edge
- {
- n = corners1[1];
- v = corners2[1];
- // Left side x -> Right side x
- m = corners1[0];
- u = corners2[2];
- px = dataPtr + (int)(n + t) * widthStep + (int)m * nChan;
- gray1 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- px = dataPtr + (int)(v + t) * widthStep + (int)u * nChan;
- gray2 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- edgeDiff[0] += Math.Abs(gray1 - gray2);
- // Right side x -> Left side x
- m = corners1[2];
- u = corners2[0];
- px = dataPtr + (int)(n + t) * widthStep + (int)m * nChan;
- gray1 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- px = dataPtr + (int)(v + t) * widthStep + (int)u * nChan;
- gray2 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- edgeDiff[1] += Math.Abs(gray1 - gray2);
- }
- // Get the average difference of values between edges
- edgeDiff[0] = (int)Math.Round((edgeDiff[0] - 255) / edgeSize1); // [0 ... 255]
- edgeDiff[1] = (int)Math.Round((edgeDiff[1] - 255) / edgeSize1); // [0 ... 255]
- }
- else if (runDiffSizeEdges)
- {
- // Different Sized Edges
- // Discover smaller Edge
- double sF, edgeStatic;
- double[] sqr_zoom, sqr_static;
- if (edgeSize1 > edgeSize2)
- {
- // Smaller Edge1
- sF = edgeSize1 / edgeSize2;
- sqr_zoom = corners2;
- sqr_static = corners1;
- edgeStatic = edgeSize1;
- // img1Ptr has the static
- img1Ptr = (corners1[5] == 1) ? dataPtrFinal : dataPtr;
- img2Ptr = (corners2[5] == 1) ? dataPtrFinal : dataPtr;
- }
- else
- {
- // Smaller Edge2
- sF = edgeSize2 / edgeSize1;
- sqr_zoom = corners1;
- sqr_static = corners2;
- edgeStatic = edgeSize2;
- // img1Ptr has the static
- img1Ptr = (corners2[5] == 1) ? dataPtrFinal : dataPtr;
- img2Ptr = (corners1[5] == 1) ? dataPtrFinal : dataPtr;
- }
- // Zoom Smallest Edge while comparing with the static one
- for (t = 0; t < edgeStatic; t++) // Iterate along the edge
- {
- n = sqr_static[1];
- v = sqr_zoom[1];
- // Left side x -> Right side x
- m = sqr_static[0];
- u = sqr_zoom[2];
- // Static
- px = img1Ptr + (int)(n + t) * widthStep + (int)m * nChan;
- gray1 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- // Zoom
- px = img2Ptr + (int)(v + t * (1 / sF)) * widthStep + (int)u * nChan;
- gray2 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- edgeDiff[0] += Math.Abs(gray1 - gray2);
- // Right side x -> Left side x
- m = sqr_static[2];
- u = sqr_zoom[0];
- // Static
- px = img1Ptr + (int)(n + t) * widthStep + (int)m * nChan;
- gray1 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- // Zoom
- px = img2Ptr + (int)(v + t * (1 / sF)) * widthStep + (int)u * nChan;
- gray2 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- edgeDiff[1] += Math.Abs(gray1 - gray2);
- }
- // Get the average difference of values between edges
- edgeDiff[0] = (int)Math.Round((edgeDiff[0] - 255) / edgeStatic); // [0 ... 255]
- edgeDiff[1] = (int)Math.Round((edgeDiff[1] - 255) / edgeStatic); // [0 ... 255]
- }
- // ---------------------------------------------------------- Top & Bottom edges
- // Top edges
- edgeSize1 = corners1[2] - corners1[0] + 1;
- edgeSize2 = corners2[2] - corners2[0] + 1;
- if (edgeSize1 == edgeSize2) // Level2. Length of edge must be the same
- {
- // Equal Edges
- for (t = 0; t < edgeSize1; t++) // Iterate along the edge
- {
- m = corners1[0];
- u = corners2[0];
- // Top side y -> Bottom side y
- n = corners1[1];
- v = corners2[3];
- px = dataPtr + (int)n * widthStep + (int)(m + t) * nChan;
- gray1 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- px = dataPtr + (int)v * widthStep + (int)(u + t) * nChan;
- gray2 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- edgeDiff[2] += Math.Abs(gray1 - gray2);
- // Bottom side y -> Top side y
- n = corners1[3];
- v = corners2[1];
- px = dataPtr + (int)n * widthStep + (int)(m + t) * nChan;
- gray1 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- px = dataPtr + (int)v * widthStep + (int)(u + t) * nChan;
- gray2 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- edgeDiff[3] += Math.Abs(gray1 - gray2);
- }
- // Get the average difference of values between edges
- edgeDiff[2] = (int)Math.Round((edgeDiff[2] - 255) / edgeSize1); // [0 ... 255]
- edgeDiff[3] = (int)Math.Round((edgeDiff[3] - 255) / edgeSize1); // [0 ... 255]
- }
- else if (runDiffSizeEdges)
- {
- // Different Sized Edges
- // Discover smaller Edge
- double sF, edgeStatic;
- double[] sqr_zoom, sqr_static;
- if (edgeSize1 > edgeSize2)
- {
- // Smaller Edge1
- sF = edgeSize1 / edgeSize2;
- sqr_zoom = corners2;
- sqr_static = corners1;
- edgeStatic = edgeSize1;
- // img1Ptr has the static
- img1Ptr = (corners1[5] == 1) ? dataPtrFinal : dataPtr;
- img2Ptr = (corners2[5] == 1) ? dataPtrFinal : dataPtr;
- }
- else
- {
- // Smaller Edge2
- sF = edgeSize2 / edgeSize1;
- sqr_zoom = corners1;
- sqr_static = corners2;
- edgeStatic = edgeSize2;
- // img1Ptr has the static
- img1Ptr = (corners2[5] == 1) ? dataPtrFinal : dataPtr;
- img2Ptr = (corners1[5] == 1) ? dataPtrFinal : dataPtr;
- }
- // Zoom Smallest Edge while comparing with the static one
- for (t = 0; t < edgeStatic; t++) // Iterate along the edge
- {
- m = sqr_static[0];
- u = sqr_zoom[0];
- // Top side y -> Bottom side y
- n = sqr_static[1];
- v = sqr_zoom[3];
- // Static
- px = img1Ptr + (int)n * widthStep + (int)(m + t) * nChan;
- gray1 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- // Zoom
- px = img2Ptr + (int)v * widthStep + (int)(u + t * (1 / sF)) * nChan;
- gray2 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- edgeDiff[2] += Math.Abs(gray1 - gray2);
- // Bottom side y -> Top side y
- n = sqr_static[3];
- v = sqr_zoom[1];
- // Static
- px = img1Ptr + (int)n * widthStep + (int)(m + t) * nChan;
- gray1 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- // Zoom
- px = img2Ptr + (int)v * widthStep + (int)(u + t * (1 / sF)) * nChan;
- gray2 = (int)Math.Round((px[0] + px[1] + px[2]) / 3.0);
- edgeDiff[3] += Math.Abs(gray1 - gray2);
- }
- // Get the average difference of values between edges
- edgeDiff[2] = (int)Math.Round((edgeDiff[2] - 255) / edgeStatic); // [0 ... 255]
- edgeDiff[3] = (int)Math.Round((edgeDiff[3] - 255) / edgeStatic); // [0 ... 255]
- }
- // Store comparison with edge difference
- piece_resemblance.Add(piecesCombination, edgeDiff);
- }
- }
- return piece_resemblance;
- }
- } // End of Edge Comparison
- static public Dictionary<Tuple<int, int>, int[]> EdgeRecalculation(Image<Bgr, byte> img, Image<Bgr, byte> imgCpy, Dictionary<int, double[]> obj_list, Dictionary<Tuple<int, int>, int[]> piece_resemblance, int macro, Tuple<int, int> micro)
- {
- unsafe
- {
- MIplImage final = img.MIplImage;
- MIplImage copy = imgCpy.MIplImage;
- byte* dataPtr = (byte*)final.imageData.ToPointer(); // Pointer to the final image
- byte* dataPtrCpy = (byte*)copy.imageData.ToPointer(); // Pointer to the original image
- byte* sqr1Ptr, sqr2Ptr, AuxPtr;
- byte* dataPtrStatic = dataPtr;
- int nChan = final.nChannels;
- int widthStep = final.widthStep;
- Tuple<int, int> piecesCombination; // key piece_resemblance
- List<int> keyList = new List<int>(obj_list.Keys);
- int[] labelArray = new int[keyList.Count];
- double edgeSize1, edgeSize2;
- double n, m, u, v;
- int i, t;
- int gray1, gray2;
- if (obj_list.Count < 2)
- return null;
- foreach (Tuple<int, int> pieceIteration in piece_resemblance.Keys.ToList())
- {
- if (pieceIteration.Item1 == micro.Item1
- || pieceIteration.Item1 == micro.Item2
- || pieceIteration.Item2 == micro.Item1
- || pieceIteration.Item2 == micro.Item2)
- piece_resemblance.Remove(pieceIteration);
- }
- i = 0;
- // Pass label values from list to array
- foreach (int keyIterator in keyList)
- {
- labelArray[i] = keyIterator;
- i++;
- }
- for (i = 0; i < labelArray.Length; i++)
- {
- if (labelArray[i] != macro)
- {
- if (labelArray[i] < macro)
- piecesCombination = new Tuple<int, int>(labelArray[i], macro);
- else
- piecesCombination = new Tuple<int, int>(macro, labelArray[i]);
- // Get the corners for each object
- obj_list.TryGetValue(piecesCombination.Item1, out double[] corners1);
- obj_list.TryGetValue(piecesCombination.Item2, out double[] corners2);
- if (corners1[5] == 0)
- sqr1Ptr = dataPtrCpy;
- else
- sqr1Ptr = dataPtr;
- if (corners2[5] == 0)
- sqr2Ptr = dataPtrCpy;
- else
- sqr2Ptr = dataPtr;
- // Edge difference created here to generate a 'new' variable. Otherwise, it would overwrite the other edges.
- // Init with max contrast
- // [0] Left edge; [1] Right edge; [2] Top edge; [3] Bottom edge;
- int[] edgeDiff = new int[4] { 255, 255, 255, 255 }; // value piece_resemblance
- // ---------------------------------------------------------- Left & Right edges
- // Left edges
- edgeSize1 = corners1[3] - corners1[1] + 1;
- edgeSize2 = corners2[3] - corners2[1] + 1;
- if (edgeSize1 == edgeSize2) // Level2. Length of edge must be the same
- {
- for (t = 0; t < edgeSize1; t++) // Iterate along the edge
- {
- n = corners1[1];
- v = corners2[1];
- // Left side x -> Right side x
- m = corners1[0];
- u = corners2[2];
- AuxPtr = sqr1Ptr + (int)(n + t) * widthStep + (int)m * nChan;
- gray1 = (int)Math.Round((AuxPtr[0] + AuxPtr[1] + AuxPtr[2]) / 3.0);
- AuxPtr = sqr2Ptr + (int)(v + t) * widthStep + (int)u * nChan;
- gray2 = (int)Math.Round((AuxPtr[0] + AuxPtr[1] + AuxPtr[2]) / 3.0);
- edgeDiff[0] += Math.Abs(gray1 - gray2);
- // Right side x -> Left side x
- m = corners1[2];
- u = corners2[0];
- AuxPtr = sqr1Ptr + (int)(n + t) * widthStep + (int)m * nChan;
- gray1 = (int)Math.Round((AuxPtr[0] + AuxPtr[1] + AuxPtr[2]) / 3.0);
- AuxPtr = sqr2Ptr + (int)(v + t) * widthStep + (int)u * nChan;
- gray2 = (int)Math.Round((AuxPtr[0] + AuxPtr[1] + AuxPtr[2]) / 3.0);
- edgeDiff[1] += Math.Abs(gray1 - gray2);
- }
- // Get the average difference of values between edges
- edgeDiff[0] = (int)Math.Round((edgeDiff[0] - 255) / edgeSize1); // [0 ... 255]
- edgeDiff[1] = (int)Math.Round((edgeDiff[1] - 255) / edgeSize1); // [0 ... 255]
- }
- // ---------------------------------------------------------- Top & Bottom edges
- // Top edges
- edgeSize1 = corners1[2] - corners1[0] + 1;
- edgeSize2 = corners2[2] - corners2[0] + 1;
- if (edgeSize1 == edgeSize2) // Level2. Length of edge must be the same
- {
- for (t = 0; t < edgeSize1; t++) // Iterate along the edge
- {
- m = corners1[0];
- u = corners2[0];
- // Top side y -> Bottom side y
- n = corners1[1];
- v = corners2[3];
- AuxPtr = sqr1Ptr + (int)n * widthStep + (int)(m + t) * nChan;
- gray1 = (int)Math.Round((AuxPtr[0] + AuxPtr[1] + AuxPtr[2]) / 3.0);
- AuxPtr = sqr2Ptr + (int)v * widthStep + (int)(u + t) * nChan;
- gray2 = (int)Math.Round((AuxPtr[0] + AuxPtr[1] + AuxPtr[2]) / 3.0);
- edgeDiff[2] += Math.Abs(gray1 - gray2);
- // Bottom side y -> Top side y
- n = corners1[3];
- v = corners2[1];
- AuxPtr = sqr1Ptr + (int)n * widthStep + (int)(m + t) * nChan;
- gray1 = (int)Math.Round((AuxPtr[0] + AuxPtr[1] + AuxPtr[2]) / 3.0);
- AuxPtr = sqr2Ptr + (int)v * widthStep + (int)(u + t) * nChan;
- gray2 = (int)Math.Round((AuxPtr[0] + AuxPtr[1] + AuxPtr[2]) / 3.0);
- edgeDiff[3] += Math.Abs(gray1 - gray2);
- }
- // Get the average difference of values between edges
- edgeDiff[2] = (int)Math.Round((edgeDiff[2] - 255) / edgeSize1); // [0 ... 255]
- edgeDiff[3] = (int)Math.Round((edgeDiff[3] - 255) / edgeSize1); // [0 ... 255]
- }
- // Store comparison with edge difference
- piece_resemblance.Add(piecesCombination, edgeDiff);
- }
- }
- return piece_resemblance;
- }
- } // End of Edge Recalculation
- static public int DiscoverMacroCornerCoord(int[,] defaultMacroPos, double[] micro1, double[] micro2, int label1, int label2, out double cxm, out double cym)
- {
- int defaultPos = 0;
- // Verify if either micros are using default positions || If both are, micro1's position will have priority || If none are, fetch a new unused macro default position
- if (micro1[5] == 1)
- {
- // Iterate defaultMacroPositions to find micro1's corner
- while ((label1 != defaultMacroPos[defaultPos, 2]))
- {
- defaultPos++;
- }
- // If micro2 was also positioned in the macro img, vacate.
- if (micro2[5] == 1)
- {
- int defaultPos_aux = 0;
- while ((label2 != defaultMacroPos[defaultPos_aux, 2]))
- {
- defaultPos_aux++;
- }
- defaultMacroPos[defaultPos_aux, 2] = 0; // Mark as unused
- }
- cym = defaultMacroPos[defaultPos, 0];
- cxm = defaultMacroPos[defaultPos, 1];
- defaultMacroPos[defaultPos, 2] = label1; // Mark as used | Redudant since micro1 was already in that position
- return defaultPos;
- }
- else if (micro2[5] == 1)
- {
- // Iterate defaultMacroPositions to find micro2's corner
- while ((label2 != defaultMacroPos[defaultPos, 2]))
- {
- defaultPos++;
- }
- cym = defaultMacroPos[defaultPos, 0];
- cxm = defaultMacroPos[defaultPos, 1];
- defaultMacroPos[defaultPos, 2] = label1; // Mark as used | Redudant since micro2 was already in that position
- return defaultPos;
- }
- else if (micro1[5] == 0 && micro2[5] == 0)
- {
- // Iterate defaultMacroPositions to find the first unused position
- while (defaultMacroPos[defaultPos, 2] != 0)
- {
- defaultPos++;
- }
- cym = defaultMacroPos[defaultPos, 0];
- cxm = defaultMacroPos[defaultPos, 1];
- defaultMacroPos[defaultPos, 2] = label1; // Mark as used | Redudant since micro1 was already in that position
- return defaultPos;
- }
- else
- {
- cym = 0;
- cxm = 0;
- defaultPos = -1; // Error, somehow...
- return defaultPos;
- }
- } // End of Discover Macro Corner Coord
- static public void JoinPieces(Image<Bgr, byte> img, Image<Bgr, byte> imgCpy, Dictionary<int, double[]> obj_list)
- {
- unsafe
- {
- Image<Bgr, byte> img_aux;
- MIplImage d = img.MIplImage;
- MIplImage c = imgCpy.MIplImage;
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- byte* dataPtrCpy = (byte*)c.imageData.ToPointer(); // Pointer to the original image
- byte[] bckgrnd = new byte[3] { dataPtr[0], dataPtr[1], dataPtr[2] };
- int w = img.Width;
- int h = img.Height;
- // Divide the image in 4.
- // 0 : x
- // 1 : y
- // 2 : label assigned - 0 if not assigned
- int[,] defaultMacroPos = new int[4, 3] { {0 , 0, 0},
- {h-1 , w-1, 0},
- {0 , w-1, 0},
- {h-1 , 0, 0} };
- int defaultPos;
- if (obj_list.Count > 1)
- {
- // Clear ImgCpy - All pixels will be background
- ClearImage(img);
- // Compare all object edges with eachother.
- Dictionary<Tuple<int, int>, int[]> piece_resemblance = EdgeComparison(imgCpy, img, obj_list, false);
- // Merge All Pieces
- while (obj_list.Count > 1)
- {
- Console.WriteLine("Outter While | Current Obj_Count: {0}", obj_list.Count);
- // Merge All Pieces, that have the same edge size.
- while (obj_list.Count > 1)
- {
- Console.WriteLine("Inner While | Current Obj_Count: {0}", obj_list.Count);
- // Init Micro-cell combination variables
- Tuple<int, int> microCellCombination = new Tuple<int, int>(0, 0);
- int minContrast = 255;
- int minContIndex = 0;
- // Find the smallest value of contrast -- Find mergeable micro cells
- foreach (var edgesIterator in piece_resemblance)
- {
- for (int i = 0; i < edgesIterator.Value.Length; i++)
- {
- if (edgesIterator.Value[i] < minContrast) // Save the index (corresponds to the edge), the contrast of such edge, and the key
- {
- minContIndex = i;
- minContrast = edgesIterator.Value[i];
- microCellCombination = edgesIterator.Key;
- }
- }
- } // End of Find Smallest Value
- // CIGANAGEM!!
- // Threshold de 30, porque funca para todas as imagens.
- // Na img 11.png, a semelhança entre 2 peças erradas é de 34 (entre 2 e 5: [0] = 37, [1] = 34), porque precisa da peça escalada no meio das duas
- if (minContrast > 30)
- {
- Console.WriteLine("No valid piece combination has been found, all remaining edges have different sizes");
- break;
- }
- Console.WriteLine("New Match: {0},{1}", microCellCombination.Item1, microCellCombination.Item2);
- // Remove Micro Cells and add new Macro Cell
- obj_list.TryGetValue(microCellCombination.Item1, out double[] old_micro1);
- obj_list.TryGetValue(microCellCombination.Item2, out double[] old_micro2);
- double[] new_micro1 = new double[6],
- new_micro2 = new double[6],
- macro = new double[6];
- double w1 = old_micro1[2] - old_micro1[0] + 1,
- w2 = old_micro2[2] - old_micro2[0] + 1,
- h1 = old_micro1[3] - old_micro1[1] + 1,
- h2 = old_micro2[3] - old_micro2[1] + 1,
- wm = 0, hm = 0;
- // Calculate new micro and macro coordinates with referencial 0,0
- if (minContIndex == 0 || minContIndex == 2)
- {
- if (minContIndex == 0)
- {
- // Left Edge - Equal height , Sum width
- wm = w1 + w2;
- hm = h1;
- new_micro1[0] = w2;
- new_micro1[1] = 0;
- }
- else if (minContIndex == 2)
- {
- // Top Edge - Sum height , Equal width
- wm = w1;
- hm = h1 + h2;
- new_micro1[0] = 0;
- new_micro1[1] = h2;
- }
- // Calculate micro and macro coordinates with referencial 0,0 on the top left corner
- new_micro2[0] = 0;
- new_micro2[1] = 0;
- new_micro2[2] = w2 - 1;
- new_micro2[3] = h2 - 1;
- new_micro1[2] = wm - 1;
- new_micro1[3] = hm - 1;
- }
- else if (minContIndex == 1 || minContIndex == 3)
- {
- if (minContIndex == 1)
- {
- // Right Edge - Equal height , Sum width
- wm = w1 + w2;
- hm = h1;
- new_micro2[0] = w1;
- new_micro2[1] = 0;
- }
- else if (minContIndex == 3)
- {
- // Bottom Edge - Sum height , Equal width
- wm = w1;
- hm = h1 + h2;
- new_micro2[0] = 0;
- new_micro2[1] = h1;
- }
- // Calculate micro and macro coordinates with referencial 0,0 on the top left corner
- new_micro1[0] = 0;
- new_micro1[1] = 0;
- new_micro1[2] = w1 - 1;
- new_micro1[3] = h1 - 1;
- new_micro2[2] = wm - 1;
- new_micro2[3] = hm - 1;
- } // End of 'Switch' minContIndex
- defaultPos = DiscoverMacroCornerCoord(defaultMacroPos, old_micro1, old_micro2, microCellCombination.Item1, microCellCombination.Item2, out double cxm, out double cym);
- Console.WriteLine("Macro Position: {0} ({1},{2})", defaultPos, cxm, cym);
- // At this phase, we have chosen the corner for the new macro cell
- // Calculate where each micro will land in the final img
- switch (defaultPos)
- {
- case 0:
- // Same has having 0 ref.
- // Do nothing
- macro[0] = cxm; // Top Left X
- macro[1] = cym; // Top Left Y
- macro[2] = cxm + (wm - 1); // Bottom Right X
- macro[3] = cym + (hm - 1); // Bottom Right Y
- break;
- case 1:
- // Move Up Left
- new_micro1[0] = cxm - (wm - 1) + new_micro1[0];
- new_micro1[1] = cym - (hm - 1) + new_micro1[1];
- new_micro1[2] = cxm - (wm - 1) + new_micro1[2];
- new_micro1[3] = cym - (hm - 1) + new_micro1[3];
- new_micro2[0] = cxm - (wm - 1) + new_micro2[0];
- new_micro2[1] = cym - (hm - 1) + new_micro2[1];
- new_micro2[2] = cxm - (wm - 1) + new_micro2[2];
- new_micro2[3] = cym - (hm - 1) + new_micro2[3];
- macro[0] = cxm - (wm - 1); // Top Left X
- macro[1] = cym - (hm - 1); // Top Left Y
- macro[2] = cxm; // Bottom Right X
- macro[3] = cym; // Bottom Right Y
- break;
- case 2:
- // Move Left
- new_micro1[0] = cxm - (wm - 1) + new_micro1[0];
- new_micro1[2] = cxm - (wm - 1) + new_micro1[2];
- new_micro2[0] = cxm - (wm - 1) + new_micro2[0];
- new_micro2[2] = cxm - (wm - 1) + new_micro2[2];
- macro[0] = cxm - (wm - 1); // Top Left X
- macro[1] = cym; // Top Left Y
- macro[2] = cxm; // Bottom Right X
- macro[3] = cym + (hm - 1); // Bottom Right Y
- break;
- case 3:
- // Move Up
- new_micro1[1] = cym - (hm - 1) + new_micro1[1];
- new_micro1[3] = cym - (hm - 1) + new_micro1[3];
- new_micro2[1] = cym - (hm - 1) + new_micro2[1];
- new_micro2[3] = cym - (hm - 1) + new_micro2[3];
- macro[0] = cxm; // Top Left X
- macro[1] = cym - (hm - 1); // Top Left Y
- macro[2] = cxm + (wm - 1); // Bottom Right X
- macro[3] = cym; // Bottom Right Y
- break;
- } // End of Switch defaultPos
- macro[4] = 0; // Angle
- macro[5] = 1; // Positioned in ImgFinal
- // Translate micros: To (image) - From (image)
- // img - Final
- // imgCpy - Original
- if (old_micro1[5] == 1 || old_micro2[5] == 1)
- {
- img_aux = img.Copy();
- // Clear Micros from the image
- if (old_micro1[5] == 1)
- ClearTrace(img, old_micro1, bckgrnd); // Remove micro1 Trace from final img
- if (old_micro2[5] == 1)
- ClearTrace(img, old_micro2, bckgrnd); // Remove micro2 Trace from final img
- if (old_micro1[5] == 1)
- {
- Console.WriteLine("Moving Micro1");
- Translation__xy_NoReplace(img, img_aux, old_micro1, new_micro1);
- }
- if (old_micro2[5] == 1)
- {
- Console.WriteLine("Moving Micro2");
- Translation__xy_NoReplace(img, img_aux, old_micro2, new_micro2);
- }
- } // End of Micro1 || Micro 2 in ImgFinal
- if (old_micro1[5] == 0)
- Translation_xy(img, imgCpy, old_micro1, new_micro1, bckgrnd); // Piece 1 in imgOriginal
- if (old_micro2[5] == 0)
- Translation_xy(img, imgCpy, old_micro2, new_micro2, bckgrnd); // Piece 2 in imgOriginal
- // Remove Micros
- obj_list.Remove(microCellCombination.Item1);
- obj_list.Remove(microCellCombination.Item2);
- // Add Macro that uses micro1 label
- obj_list.Add(microCellCombination.Item1, macro);
- // Recalculate Piece Resemblance
- EdgeRecalculation(img, imgCpy, obj_list, piece_resemblance, microCellCombination.Item1, microCellCombination);
- } // End of While objList.Count > 1 for objects with equal edge sizes
- // If there are still more than 1 object, proceed to Scale
- if (obj_list.Count > 1)
- {
- Console.WriteLine("Scaling If | Current Obj_Count: {0}", obj_list.Count);
- // Calculate Piece Resemblence
- // For all edges, even those varying in size
- piece_resemblance = EdgeComparison(imgCpy, img, obj_list, true);
- // Find least Contrast Edge Match
- // Init Micro-cell combination variables
- Tuple<int, int> microCellCombination = new Tuple<int, int>(0, 0);
- int minContrast = 255;
- int minContIndex = 0;
- // Find the smallest value of contrast -- Find mergeable micro cells
- foreach (var edgesIterator in piece_resemblance)
- {
- for (int i = 0; i < edgesIterator.Value.Length; i++)
- {
- if (edgesIterator.Value[i] < minContrast) // Save the index (corresponds to the edge), the contrast of such edge, and the key
- {
- minContIndex = i;
- minContrast = edgesIterator.Value[i];
- microCellCombination = edgesIterator.Key;
- }
- }
- } // End of Find Smallest Value
- Console.WriteLine("Scaling Match Result: [{0}] {1},{2}", minContIndex, microCellCombination.Item1, microCellCombination.Item2);
- // Get Micros
- obj_list.TryGetValue(microCellCombination.Item1, out double[] old_micro1);
- obj_list.TryGetValue(microCellCombination.Item2, out double[] old_micro2);
- double[] scale_sqr, static_sqr;
- int sum1 = 0,
- sum2 = 0,
- label_scale;
- // Find what micro to scale
- // Objects in imgFinal have priority
- // If both pieces are in the same Img, choose based upon the sums of their resemblences
- if (old_micro1[5] == old_micro2[5])
- {
- // Choose based on Resemblence
- foreach (var edgesIterator in piece_resemblance)
- {
- if (edgesIterator.Key.Item1 == microCellCombination.Item1 || edgesIterator.Key.Item2 == microCellCombination.Item1)
- {
- for (int i = 0; i < edgesIterator.Value.Length; i++)
- {
- sum1 += edgesIterator.Value[i];
- }
- }
- else if (edgesIterator.Key.Item1 == microCellCombination.Item2 || edgesIterator.Key.Item2 == microCellCombination.Item2)
- {
- for (int i = 0; i < edgesIterator.Value.Length; i++)
- {
- sum2 += edgesIterator.Value[i];
- }
- }
- } // End of Sum Resemblences
- Console.WriteLine("Sum Result: {0},{1}", sum1, sum2);
- } // End of Choose based on Resemblence
- // Design Static and Scaleable Piece
- if ((old_micro1[5] == 1 && old_micro2[5] == 0) || sum1 < sum2)
- {
- Console.WriteLine("Scaling Micro 1 | In: {0}", old_micro1[5]);
- scale_sqr = old_micro1;
- label_scale = microCellCombination.Item1;
- static_sqr = old_micro2;
- }
- else if ((old_micro2[5] == 1 && old_micro1[5] == 0) || sum2 < sum1)
- {
- Console.WriteLine("Scaling Micro 2 | In: {0}", old_micro2[5]);
- scale_sqr = old_micro2;
- label_scale = microCellCombination.Item2;
- static_sqr = old_micro1;
- }
- else
- {
- Console.WriteLine("Scaling SEGMENTATION ERRROR DUMPINxsinxwsG COOooOOOrrr€€€€");
- scale_sqr = null;
- label_scale = 0;
- static_sqr = null;
- return;
- }
- // Match Scaleable Piece to match Static Piece by calculating Scaling Factor
- double[] final_sqr;
- double scale_w = scale_sqr[2] - scale_sqr[0] + 1,
- static_w = static_sqr[2] - static_sqr[0] + 1,
- scale_h = scale_sqr[3] - scale_sqr[1] + 1,
- static_h = static_sqr[3] - static_sqr[1] + 1,
- sF = 1;
- if (minContIndex == 0 || minContIndex == 1)
- {
- // Match Static Width
- if (static_w > scale_w)
- {
- // Expand
- sF = static_w / scale_w;
- Console.WriteLine("Zoom Width with sF: {0}", sF);
- }
- else
- {
- // Contract
- sF = scale_w / static_w;
- Console.WriteLine("Unzoom Width with sF: {0}", sF);
- }
- }
- else if (minContIndex == 2 || minContIndex == 3)
- {
- // Match Static Height
- if (static_h > scale_w)
- {
- // Expand
- sF = static_h / scale_h;
- Console.WriteLine("Zoom Width with sF: {0}", sF);
- }
- else
- {
- // Contract
- sF = scale_h / static_h;
- Console.WriteLine("Unzoom Width with sF: {0}", sF);
- }
- } // End of 'Switch' minContIndex
- return;
- // Scale Scaleable Piece
- if (scale_sqr[5] == 1)
- {
- img_aux = img.Copy();
- final_sqr = Scale_Piece(img, img_aux, scale_sqr, sF, bckgrnd);
- } else
- {
- img_aux = imgCpy.Copy();
- final_sqr = Scale_Piece(imgCpy, img_aux, scale_sqr, sF, bckgrnd);
- }
- // Update Obj_List
- obj_list.Remove(label_scale);
- obj_list.Add(label_scale, final_sqr);
- } // End of If objList.Count > 1 for scaling purposes
- } // End of While objList.Count > 1
- } // End of If objList.Count > 1
- Console.WriteLine("Centering | Current Obj_Count: {0}", obj_list.Count);
- // Center the unified piece in the img
- Console.WriteLine("Centering Solved Puzzle");
- obj_list.TryGetValue(1, out double[] old_micro);
- double centercornerx = (int)(Math.Round(w / 2.0) - (Math.Round((old_micro[2] + old_micro[0]) / 2) - old_micro[0]));
- double centercornery = (int)(Math.Round(h / 2.0) - (Math.Round((old_micro[3] + old_micro[1]) / 2) - old_micro[1]));
- double[] center_sqr = new double[4] { centercornerx, centercornery, centercornerx + (old_micro[2] - old_micro[0]), centercornery + (old_micro[3] - old_micro[1]) };
- // Translate to new position
- img_aux = img.Copy();
- ClearTrace(img, old_micro, bckgrnd);
- Translation__xy_NoReplace(img, img_aux, old_micro, center_sqr);
- } // End of Unsafe
- } // End of Join Pieces
- /// <summary>
- /// Function that solves the puzzle
- /// </summary>
- /// <param name="img">Input/Output image</param>
- /// <param name="imgCopy">Image Copy</param>
- /// <param name="Pieces_positions">List of positions (Left-x,Top-y,Right-x,Bottom-y) of all detected pieces</param>
- /// <param name="Pieces_angle">List of detected pieces' angles</param>
- /// <param name="level">Level of image</param>
- static public void puzzle(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, out List<int[]> Pieces_positions, out List<int> Pieces_angle, int level)
- {
- Pieces_positions = new List<int[]>();
- Pieces_angle = new List<int>();
- Dictionary<int, double[]> obj_list;
- Dictionary<int, double[]>.Enumerator Enum;
- // Labeling of existing pieces
- int[,] labels = ImageClass.Classification(img, true, false);
- if (labels != null)
- {
- // Get a list of existing pieces properties according to their label
- obj_list = ImageClass.FindCorners(labels, img.Width, img.Height);
- Console.WriteLine("Pieces Labeled");
- // Rotate the pieces that require it.
- ImageClass.RotatePieces(img, imgCopy, labels, obj_list);
- // Merge all the pieces
- Image<Bgr, byte> img_aux = img.Copy();
- ImageClass.JoinPieces(img, img_aux, obj_list);
- Console.WriteLine("All Pieces Merged");
- img_aux.CopyTo(imgCopy); // DEBUG
- // Finish - Update out parameters
- Enum = obj_list.GetEnumerator();
- int[] sqr;
- double[] piece;
- while (Enum.MoveNext())
- {
- piece = Enum.Current.Value;
- sqr = new int[4] { (int)piece[0], (int)piece[1], (int)piece[2], (int)piece[3] };
- Pieces_positions.Add(sqr);
- Pieces_angle.Add((int)piece[4]);
- }
- } // End of Label != null
- } // End of Puzzle
- // *** Extra Functions ***
- static public void Translation_NaoConseguiMudarOMetodoDeEnderecamento(Image<Bgr, byte> img, Image<Bgr, byte> imgCopy, int dx, int dy)
- {
- unsafe
- {
- MIplImage m = imgCopy.MIplImage;
- MIplImage d = img.MIplImage;
- byte* dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the original image
- byte* dataPtr; // Pointer to the final image
- byte* o_px;
- int width = imgCopy.Width;
- int height = imgCopy.Height;
- int widthStep = m.widthStep;
- int nChan = m.nChannels; // number of channels - 3
- int padding = widthStep - nChan * width;
- int x, y;
- int x_blk_inf = 0, x_blk_sup = 0, y_blk_inf = 0, y_blk_sup = 0;
- int x_img_inf = 0, x_img_sup = 0, y_img_inf = 0, y_img_sup = 0;
- if (dx > 0)
- {
- x_blk_inf = 0;
- x_blk_sup = dx;
- x_img_inf = dx;
- x_img_sup = width;
- }
- else if (dx < 0)
- {
- x_img_inf = 0;
- x_img_sup = width + dx;
- x_blk_inf = width + dx;
- x_blk_sup = width;
- }
- if (dy > 0)
- {
- y_blk_inf = 0;
- y_blk_sup = dy;
- y_img_inf = dy;
- y_img_sup = height;
- }
- else if (dy < 0)
- {
- y_img_inf = 0;
- y_img_sup = height + dy;
- y_blk_inf = height + dy;
- y_blk_sup = height;
- }
- if (nChan == 3) // image in RGB
- {
- dataPtr = (byte*)d.imageData.ToPointer() + x_blk_inf * nChan;
- // Process dx bigger rectangle
- for (y = 0; y < height; y++)
- {
- for (x = x_blk_inf; x < x_blk_sup; x++)
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- dataPtr += nChan;
- }
- dataPtr += padding + (x_blk_sup - x_blk_inf) * nChan;
- }
- dataPtr = (byte*)d.imageData.ToPointer() + x_img_inf * nChan + y_blk_inf * widthStep;
- // Process dy smaller rectangle
- for (y = y_blk_inf; y < y_blk_sup; y++)
- {
- for (x = x_img_inf; x < x_img_sup; x++)
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 0;
- dataPtr += nChan;
- }
- dataPtr += padding + (x_img_sup - x_img_inf) * nChan;
- }
- dataPtr = (byte*)d.imageData.ToPointer() + y_img_inf * nChan + y_img_inf * widthStep;
- // Process image rectangle
- for (y = y_img_inf; y < y_img_sup; y++)
- {
- //diff_y_ws = (y - dy) * widthStep;
- for (x = y_img_inf; x < x_img_sup; x++)
- {
- o_px = (dataPtr_org + (y - dy) * widthStep + (x - dx) * nChan);
- dataPtr[0] = (byte)o_px[0];
- dataPtr[1] = (byte)o_px[1];
- dataPtr[2] = (byte)o_px[2];
- dataPtr += nChan;
- }
- dataPtr += padding + (x_img_sup - y_img_inf) * nChan;
- }
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Translation
- // To Finish: Upper Margin || Check Dilate Flag, it is possible not right
- static public void Dilation_3x3(Image<Bgr, byte> img, Image<Bgr, byte> imgUndo, bool[,] matrix)
- {
- unsafe
- {
- MIplImage d = img.MIplImage;
- MIplImage m = imgUndo.MIplImage;
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- byte* dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the final image
- byte* px;
- int w = img.Width;
- int h = img.Height;
- int nChan = d.nChannels;
- int widthStep = d.widthStep;
- int padding = widthStep - nChan * w;
- int x, y;
- if (nChan == 3)
- {
- dataPtr += nChan + widthStep;
- dataPtr_org += nChan + widthStep;
- for (y = 1; y < h - 1; y++)
- {
- for (x = 1; x < w - 1; x++)
- {
- // Kernel
- bool dilate = false;
- byte px_value = 0;
- // Loop Y
- for (int i = 0; i < 3; i++)
- {
- if (dilate)
- {
- if (dataPtr[0] != px_value)
- {
- dataPtr[0] = 0;
- dataPtr[1] = 0;
- dataPtr[2] = 255;
- }
- else
- {
- dataPtr[0] = px_value;
- dataPtr[1] = px_value;
- dataPtr[2] = px_value;
- }
- break;
- }
- // Loop X
- for (int j = 0; j < 3; j++)
- {
- if (matrix[i, j])
- {
- // True Value in Mask
- px = dataPtr_org + (j - 1) * nChan + (i - 1) * widthStep;
- if (px[0] != 255 && px[1] != 255 && px[2] != 255)
- {
- dilate = true;
- px_value = px[0];
- break;
- }
- }
- } // End of Kernel X Loop
- } // End of Kernel Y Loop
- dataPtr += nChan;
- dataPtr_org += nChan;
- } // End of X Loop
- dataPtr += padding + 2 * nChan;
- dataPtr_org += padding + 2 * nChan;
- } // End of Y Loop
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Dilation 3x3
- // To Finish
- private const int HnM_Bckgrd = 255;
- static public void HitnMiss_3x3(Image<Bgr, byte> img, Image<Bgr, byte> imgUndo, int[,] matrix)
- {
- unsafe
- {
- MIplImage d = img.MIplImage;
- MIplImage m = imgUndo.MIplImage;
- byte* dataPtr = (byte*)d.imageData.ToPointer(); // Pointer to the final image
- byte* dataPtr_org = (byte*)m.imageData.ToPointer(); // Pointer to the final image
- byte* px;
- int w = img.Width;
- int h = img.Height;
- int nChan = d.nChannels;
- int widthStep = d.widthStep;
- int padding = widthStep - nChan * w;
- int x, y;
- Tuple<int, int, int> corner;
- List<Tuple<int, int, int>> corners_list = new List<Tuple<int, int, int>>();
- bool break_flag;
- if (nChan == 3)
- {
- // Core
- dataPtr += nChan + widthStep;
- dataPtr_org += nChan + widthStep;
- for (y = 1; y < h - 1; y++)
- {
- for (x = 1; x < w - 1; x++)
- {
- // Mask Kernel with rotation
- for (int r = 0; r < 3; r++)
- {
- break_flag = false;
- for (int i = 0; i < 3; i++)
- {
- if (break_flag)
- break;
- for (int j = 0; j < 3; j++)
- {
- px = dataPtr_org + (j - 1) * nChan + (i - 1) * widthStep;
- if (matrix[i, j] == 0)
- {
- if (px[0] == HnM_Bckgrd && px[1] == HnM_Bckgrd && px[2] == HnM_Bckgrd)
- continue;
- else
- {
- break_flag = true;
- break;
- }
- }
- else if (matrix[i, j] == 1)
- {
- if (px[0] != HnM_Bckgrd && px[1] != HnM_Bckgrd && px[2] != HnM_Bckgrd)
- continue;
- else
- {
- break_flag = true;
- break;
- }
- }
- } // End of Kernel X Loop
- } // End of Kernel Y Loop
- if (!break_flag)
- {
- // Pixel Matches Mask, add to list
- corner = new Tuple<int, int, int>(r, x, y);
- corners_list.Add(corner);
- }
- // Rotate Mask for the next iteration
- // Rotate45d_3x3Mask(&m);
- } // End of Mask Rotation
- dataPtr += nChan;
- dataPtr_org += nChan;
- } // End of X Loop
- dataPtr += padding + 2 * nChan;
- dataPtr_org += padding + 2 * nChan;
- } // End of Y Loop
- } // End of nChan = 3
- } // End of Unsafe
- } // End of Hit n Miss
- } // End of ImageClass
- } // End of NameSpace OpenCV
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement