public static Image <Bgr, float> Bgr2Hsv( Image <Gray, float> b, Image <Gray, float> g, Image <Gray, float> r ) { var v = r.Max(g).Max(b); var h = new Image <Gray, float>(v.Size); var s = v - r.Min(g).Min(b); Mat z = new Mat(); var zeroAux = new Image <Gray, float>(s.Size); zeroAux.SetZero(); //z = ~s; CvInvoke.Compare(s, zeroAux, z, Emgu.CV.CvEnum.CmpType.Equal); //s(z) = 1; s.Mat.SetTo(new MCvScalar(1), z); //k = (r == v); var k = new Mat(); CvInvoke.Compare(r, v, k, Emgu.CV.CvEnum.CmpType.Equal); //h(k) = (g(k) - b(k))./ s(k); (g - b).Mul(1.0 / s).Mat.CopyTo(h, k); //k = (g == v); CvInvoke.Compare(g, v, k, Emgu.CV.CvEnum.CmpType.Equal); //h(k) = 2 + (b(k) - r(k))./ s(k); (2 + (b - r).Mul(1.0 / s)).Mat.CopyTo(h, k); //k = (b == v); CvInvoke.Compare(b, v, k, Emgu.CV.CvEnum.CmpType.Equal); //h(k) = 4 + (r(k) - g(k))./ s(k); (4 + (r - g).Mul(1.0 / s)).Mat.CopyTo(h, k); //h = h / 6; h._Mul(1.0 / 6.0); //k = (h < 0); CvInvoke.Compare(h, zeroAux, k, Emgu.CV.CvEnum.CmpType.Equal); //h(k) = h(k) + 1; (h + 1).Mat.CopyTo(h, k); //h(z) = 0; h.Mat.SetTo(new MCvScalar(0), z); //tmp = s./ v; var tmp = s.Mul(1.0 / v); //tmp(z) = 0; tmp.Mat.SetTo(new MCvScalar(0), z); //k = (v~= 0); //CvInvoke.FindNonZero(v, k); CvInvoke.Compare(v, zeroAux, k, Emgu.CV.CvEnum.CmpType.NotEqual); //s(k) = tmp(k); tmp.Mat.CopyTo(s, k); //s(~v) = 0; CvInvoke.BitwiseNot(k, k); s.Mat.SetTo(new MCvScalar(0), k); return(new Image <Bgr, float>(new Image <Gray, float>[] { v, s, h })); }
public void Process(string imagePath) { var im = CvInvoke.Imread(imagePath, Emgu.CV.CvEnum.ImreadModes.Grayscale); Mat imx = new Mat(), th = new Mat(); CvInvoke.MedianBlur(im, imx, 3); CvInvoke.Resize(imx, th, new Size(50, 50), 0, 0, Inter.Area); CvInvoke.GaussianBlur(th, im, new Size(7, 7), 0); CvInvoke.Resize(im, th, imx.Size, 0, 0, Inter.Linear); CvInvoke.Compare(imx, th, im, CmpType.GreaterThan); var imrgb = new Mat(im.Rows, im.Cols, DepthType.Cv8U, 3); CvInvoke.CvtColor(im, imrgb, ColorConversion.Gray2Bgr); var contours = new Emgu.CV.Util.VectorOfVectorOfPoint(); CvInvoke.FindContours(im, contours, null, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple); var ca = contours.ToArrayOfArray(); var cells = new List <Cell>(); List <double> ca_aa = new List <double>(ca.Length); for (int i = 0; i < ca.Length; i++) { var c = new Cell(ca[i]); cells.Add(c); ca_aa.Add(c.sarea); } ca_aa.Sort(); double ca_max = 0, ca_min = 0; for (int i = 100; i >= 0 && ca_aa[i] / ca_aa[i + 1] < 1.01; i--) { ca_max = -ca_aa[i]; } for (int i = 100; i < ca_aa.Count && ca_aa[i] / ca_aa[i + 1] < 1.01; i++) { ca_min = -ca_aa[i]; } double side_avg = Math.Sqrt((ca_min + ca_max) / 2); List <Cell> gridCells = new List <Cell>(); for (int i = 0; i < ca.Length; i++) { var col = colors[i % colors.Count]; var c = cells[i]; if (c.area > ca_max || c.area < ca_min) { continue; } c.FindCenter(); double minR = c.sidelength / 2.25; //CvInvoke.Circle(imrgb, c.cp, (int)minR, col, 1); bool ok = true; var minR2 = minR * minR; for (int j = 0; j < c.ca.Length; j++) { if (c.Dist2(c.ca[j]) < minR2) { ok = false; } } //for (int j = 1; j < c.ca.Length; j++) // CvInvoke.Line(imrgb, c.ca[j - 1], c.ca[j], col, ok ? 9 : 3); if (ok) { gridCells.Add(c); } } double maxCentDist2 = 2 * side_avg * side_avg; for (int i = 0; i < gridCells.Count; i++) { var a = gridCells[i]; for (int j = 0; j < gridCells.Count; j++) { var b = gridCells[j]; if (i == j) { continue; } if (a.Dist2(b) < maxCentDist2) { var d = a.Diff(b); bool isX = Math.Abs(d.X) > Math.Abs(d.Y); Cell.Dir dir = isX ? d.X < 0 ? Cell.Dir.Left : Cell.Dir.Right : d.Y < 0 ? Cell.Dir.Up : Cell.Dir.Down; a.Link(b, dir); //CvInvoke.Line(imrgb, a.cp, b.cp, new MCvScalar(0, 255, isX ? 255 : 0), 3); } } } Queue <Cell> qc = new Queue <Cell>(); gridCells[0].SetGridIndex(new Point()); // Arbitrary Origo qc.Enqueue(gridCells[0]); while (qc.Count > 0) { var c = qc.Dequeue(); foreach (var nc in c.neighbours) { if (nc != null && !nc.hasGridIndex) { qc.Enqueue(nc); } } c.CalcNeighboursGridIndex(); } int gixr = (from c in gridCells select c.gi.X).Min(); int giyr = (from c in gridCells select c.gi.Y).Min(); foreach (var c in cells) { c.gi = new Point(c.gi.X - gixr, c.gi.Y - giyr); } gixr = (from c in gridCells select c.gi.X).Max() + 1; giyr = (from c in gridCells select c.gi.Y).Max() + 1; var gridEst = new GridEstimator(); foreach (var c in gridCells) { gridEst.Add(c.gi, c.cpf); } gridEst.Process(); for (int Xi = 0; Xi < gixr; Xi++) { Point p1 = gridEst.GetP(Xi + 0.5f, 0.5f); Point p2 = gridEst.GetP(Xi + 0.5f, giyr - 0.5f); CvInvoke.Line(imrgb, p1, p2, new MCvScalar(0, 100, 255), 5); } for (int Yi = 0; Yi < giyr; Yi++) { Point p1 = gridEst.GetP(0.5f, Yi + 0.5f); Point p2 = gridEst.GetP(gixr - 0.5f, Yi + 0.5f); CvInvoke.Line(imrgb, p1, p2, new MCvScalar(0, 100, 255), 5); } Cell[,] cg = new Cell[gixr, giyr]; foreach (var c in gridCells) { cg[c.gi.X, c.gi.Y] = c; } for (int xi = 0; xi < gixr; xi++) { for (int yi = 0; yi < giyr; yi++) { var c = cg[xi, yi]; if (c == null) { continue; } var col = colors[(xi + yi) % colors.Count]; double minR = c.sidelength / 2.25; //CvInvoke.Circle(imrgb, c.cp, (int)minR, col, 4); } } var sidesize = (int)(side_avg * 0.8); for (int xi = 0; xi < gixr; xi++) { for (int yi = 0; yi < giyr; yi++) { var c = cg[xi, yi]; if (c == null) { continue; } c.image = c.ExtractImage(imx, sidesize); c.imMask = c.ExtractImage(im, sidesize); } } List <float> diffs = new List <float>(); for (int xi = 0; xi < gixr; xi++) { for (int yi = 0; yi < giyr; yi++) { var c = cg[xi, yi]; if (c == null) { continue; } var t = cg[10, 10]; var r = c.Match(t); diffs.Add(r); } } float diffMax = diffs.Max(); Mat gridImage = new Mat(sidesize * giyr, sidesize * gixr, DepthType.Cv8U, 3); gridImage.SetTo(new MCvScalar(128, 128, 128)); Mat gridMatchImage = new Mat(sidesize * giyr, sidesize * gixr, DepthType.Cv8U, 3); gridMatchImage.SetTo(new MCvScalar(128, 128, 128)); var templateCell = cg[10, 10]; for (int xi = 0; xi < gixr; xi++) { for (int yi = 0; yi < giyr; yi++) { var c = cg[xi, yi]; if (c == null) { continue; } var r = c.Match(templateCell); var imrgb2 = new Mat(); CvInvoke.CvtColor(c.image, imrgb2, ColorConversion.Gray2Bgr); Mat w = new Mat(gridImage, new Rectangle(new Point(xi * sidesize, yi * sidesize), c.image.Size)); imrgb2.CopyTo(w); w = new Mat(gridMatchImage, new Rectangle(new Point(xi * sidesize, yi * sidesize), c.image.Size)); int rr = (int)(r / diffMax * 255); w.SetTo(new MCvScalar(0, 255 - rr, rr)); imrgb2.CopyTo(w, c.imMask); } } new Emgu.CV.UI.ImageViewer(gridImage, "gridImage").Show(); // Allows zoom and pan //CvInvoke.Imshow("gridImage", gridImage); CvInvoke.Imshow("gridMatchImage", gridMatchImage); new Emgu.CV.UI.ImageViewer(imrgb, "work grid").Show(); // Allows zoom and pan // CvInvoke.Imshow("work grid", imrgb); CvInvoke.Imwrite("work grid.png", imrgb); while (CvInvoke.WaitKey(100) == -1) { ; } }
public void ProcessCopyOverNCenter(UMat magT, UMat phT, Rectangle selRoi, out double selRoiMinMagVal, out double selRoiMaxMagVal, out Point selRoiMinMagLoc, out Point selRoiMaxMagLoc, out Rectangle ctrRoi, out Point ctrRoiMaxMagLoc, out Rectangle ltdSelRoi, UMat magFoT, UMat phFoT) { ///Takes the selected roi, copies and pastes it ///onto a zero image with its maximum value at the bottom-right ///of the centre, updates magFoT and phFoT. //create UMats filled with '0's to "paste" the first-order's Transform into magFoT.Create(magT.Rows, magT.Cols, DepthType.Cv32F, 1); magFoT.SetTo(new MCvScalar(0)); magFoT.CopyTo(phFoT); if (_ManualCentering) { selRoiMinMagVal = 0; selRoiMaxMagVal = 0; selRoiMinMagLoc = new Point(0, 0); selRoiMaxMagLoc = fTView.GetManualCent() - (Size)selRoi.Location; } else { using (UMat magSelT = new UMat(magT, selRoi)) { // get the values and locations of maximum and minimum points // for each channel, but we only have 1 channel // so we only use the [0] index. magSelT.MinMax(out double[] selRoiMinMagValues, out double[] selRoiMaxMagValues, out Point[] selRoiMinMagLocations, out Point[] selRoiMaxMagLocations); selRoiMinMagVal = selRoiMinMagValues[0]; selRoiMaxMagVal = selRoiMaxMagValues[0]; selRoiMinMagLoc = selRoiMinMagLocations[0]; selRoiMaxMagLoc = selRoiMaxMagLocations[0]; if (_WeightCentering) { using (UMat Mask = magSelT.Clone()) { UMat aaaaa = new UMat(); Mask.SetTo(new MCvScalar((long)(selRoiMaxMagVal * 0.3))); CvInvoke.Compare(magSelT, Mask, aaaaa, CmpType.GreaterEqual); Moments m = CvInvoke.Moments(aaaaa, true); selRoiMaxMagLoc = new Point((int)(m.M10 / m.M00), (int)(m.M01 / m.M00)); } } } } //find 0Hz point in image, which is at the bottom-right of the centre, //because the width and height are even numbers as I cropped them //earlier in SwitchQuadrants(). There's no +1 because coordinates //start at index 0. Point foT0HzLoc = new Point(magFoT.Cols / 2, magFoT.Rows / 2); //calculate ctrRoi on foT to paste into, where the copied's max value //is at foT's 0Hz point. ctrRoi = new Rectangle(foT0HzLoc - (Size)selRoiMaxMagLoc, selRoi.Size); //it's possible for ctrRoi to go out of the image if you select //a region more than (width or height)/2, and the max value point //is at a corner, so we limit it. However, this means that the sizes //of selRoi and ctrRoi are different, so we limit selRoi too. LimitRoiToImage2(magFoT, ref ctrRoi); //calculate ltdSelRoi by going backwards and "pasting" ctrRoi //on magT. //find the new maxMagLoc in ctrRoi (it might change after limiting) ctrRoiMaxMagLoc = foT0HzLoc - (Size)ctrRoi.Location; Point selRoiMaxMagAbsLoc = selRoi.Location + (Size)selRoiMaxMagLoc; //location relative to origin of magT ltdSelRoi = new Rectangle(selRoiMaxMagAbsLoc - (Size)ctrRoiMaxMagLoc, ctrRoi.Size); ; //finally, copy ltdSelRoi in T to ctrRoi in foT using (UMat magLtdSelT = new UMat(magT, ltdSelRoi), phLtdSelT = new UMat(phT, ltdSelRoi), magCtrFoT = new UMat(magFoT, ctrRoi), phCtrFoT = new UMat(phFoT, ctrRoi)) { magLtdSelT.CopyTo(magCtrFoT); phLtdSelT.CopyTo(phCtrFoT); } }
public void GrabCut3(Vector2 point, PAINTING_MODE pm) { SaveToUndoState(); if (pm == PAINTING_MODE.BRUSH) { CvInvoke.Circle(WallMask, point.toPoint(), 30, White, -1); WallMask.ApplyToTexture2D(OutputMaskTexture); return; } if (pm == PAINTING_MODE.ERASER) { CvInvoke.Circle(WallMask, point.toPoint(), 30, Black, -1); WallMask.ApplyToTexture2D(OutputMaskTexture); return; } Mat img2 = CameraMat24.Clone(); Mat imgTarget = CameraMat24.Clone(); //Color de llenado (Rojo para el primer color, Verde para el segundo color switch (SelectedColorIndex) { case 0: imgTarget.SetTo(Red); break; case 1: imgTarget.SetTo(Green); break; case 2: imgTarget.SetTo(Blue); break; } Mat imgref = CameraMat24.Clone(); //Color de Referencia (Rosado Perfecto) imgref.SetTo(Pink); Mat maskEdges2 = EdgeMap.Clone(); Mat mask1 = new Mat(img2.Rows, img2.Cols, DepthType.Cv8U, 1); Mat mask3 = new Mat(img2.Rows, img2.Cols, DepthType.Cv8U, 3); mask3.SetTo(Black); Point PixelPoint = point.toPoint(); int Offset = (PixelPoint.Y * img2.Width + PixelPoint.X) * 3; int R = CameraColors24[Offset]; int G = CameraColors24[Offset + 1]; int B = CameraColors24[Offset + 2]; MCvScalar LoDiff = new MCvScalar(Mathf.Min(DeltaColor2, B), Mathf.Min(DeltaColor2, G), Mathf.Min(DeltaColor2, R)); MCvScalar UpDiff = new MCvScalar(Mathf.Min(DeltaColor2, 255 - B), Mathf.Min(DeltaColor2, 255 - G), Mathf.Min(DeltaColor2, 255 - R)); Rectangle rect = new Rectangle(); switch (pm) { case PAINTING_MODE.FLOODFILL: CvInvoke.FloodFill(img2, maskEdges2, PixelPoint, Pink, out rect, LoDiff, UpDiff, Connectivity.FourConnected); CvInvoke.Compare(img2, imgref, mask3, CmpType.Equal); //Deben ser todos de 3 canales, mask3 contiene la máscara a pintar CvInvoke.Dilate(mask3, mask3, null, Anchor, 2, BorderType.Default, Black); CvInvoke.Blur(mask3, mask3, new Size(4, 4), Anchor); CvInvoke.ExtractChannel(mask3, mask1, 0); //Se extrae un canal para usar como máscara CvInvoke.BitwiseNot(mask3, mask3); //Negativo de la zona a pintar, para despintar antes de pintar CvInvoke.BitwiseAnd(WallMask, mask3, WallMask); //Despinta primero CvInvoke.BitwiseOr(WallMask, imgTarget, WallMask, mask1); //Pinta de rojo, verde o azul la textura objetivo break; } WallMask.ApplyToTexture2D(OutputMaskTexture); img2.Dispose(); imgref.Dispose(); imgTarget.Dispose(); mask1.Dispose(); mask3.Dispose(); maskEdges2.Dispose(); }
/// <summary> /// function rgb=hsl2rgb(hsl_in) /// </summary> /// <param name="bgrimage"></param> /// <returns></returns> public static Image <Bgr, byte> Hsl2Bgr(Image <Bgr, byte> bgrimage) { var doubleBgr = bgrimage.Convert <Bgr, float>() / 255; var numPoints = bgrimage.Rows * bgrimage.Cols; var H = new Image <Gray, float>(1, numPoints); var S = new Image <Gray, float>(1, numPoints); var L = new Image <Gray, float>(1, numPoints); var channels = doubleBgr.Split(); MatHelper.CopyTo(ref channels[2], 0, 0, channels[2].Cols, channels[0].Rows, ref H, 0, 0, 1, numPoints); MatHelper.CopyTo(ref channels[1], 0, 0, channels[1].Cols, channels[1].Rows, ref S, 0, 0, 1, numPoints); MatHelper.CopyTo(ref channels[0], 0, 0, channels[0].Cols, channels[2].Rows, ref L, 0, 0, 1, numPoints); Image <Gray, float> auxImage = new Image <Gray, float>(L.Size); Image <Gray, Byte> auxImageByte = new Image <Gray, Byte>(L.Size); auxImage.SetValue(new Gray(0.5)); Mat lowlidx = new Mat(L.Rows, L.Cols, Emgu.CV.CvEnum.DepthType.Cv8U, L.NumberOfChannels); Mat nonlowlidx = new Mat(L.Rows, L.Cols, Emgu.CV.CvEnum.DepthType.Cv8U, L.NumberOfChannels); CvInvoke.Compare(L, auxImage, lowlidx, Emgu.CV.CvEnum.CmpType.LessEqual); CvInvoke.BitwiseNot(lowlidx, nonlowlidx); //var lowLidx = L.ThresholdBinaryInv(new Gray(1.0 / 2.0), new Gray(1.0)); //Mat q = new Mat(L.Rows, L.Cols, , L.NumberOfChannels); //Mat p = new Mat(L.Rows, L.Cols, Emgu.CV.CvEnum.DepthType.Cv8U, L.NumberOfChannels); var partial1 = 1 + S; partial1._Mul(L); auxImageByte.SetValue(new Gray(255)); CvInvoke.Divide(lowlidx, auxImageByte, lowlidx); Mat lowlidxFloat = new Mat(); lowlidx.ConvertTo(lowlidxFloat, Emgu.CV.CvEnum.DepthType.Cv32F); CvInvoke.Multiply(partial1.Mat, lowlidxFloat, partial1.Mat); CvInvoke.Divide(nonlowlidx, auxImageByte, nonlowlidx); var partial2 = L.Mul(S); Mat nonlowlidxFloat = new Mat(); nonlowlidx.ConvertTo(nonlowlidxFloat, Emgu.CV.CvEnum.DepthType.Cv32F); CvInvoke.Multiply(partial2.Mat, nonlowlidxFloat, partial2.Mat); partial2 = L + S - partial2; var q = partial1 + partial2; var p = 2 * L - q; var hk = H; var t1 = hk + 1 / 3.0; var t2 = hk; var t3 = hk - 1 / 3.0; var underidx1 = t1.ThresholdBinaryInv(new Gray(0), new Gray(1)); var underidx2 = t2.ThresholdBinaryInv(new Gray(0), new Gray(1)); var underidx3 = t3.ThresholdBinaryInv(new Gray(0), new Gray(1)); var overidx1 = t1.ThresholdBinary(new Gray(1), new Gray(1)); var overidx2 = t2.ThresholdBinary(new Gray(1), new Gray(1)); var overidx3 = t3.ThresholdBinary(new Gray(1), new Gray(1)); var t = new Image <Bgr, float>(new Image <Gray, float>[] { t1, t2, t3 }); var underidx = new Image <Bgr, float>(new Image <Gray, float>[] { underidx2, underidx2, underidx3 }); var overidx = new Image <Bgr, float>(new Image <Gray, float>[] { overidx1, overidx2, overidx3 }); t = t + underidx - overidx; t1.Dispose(); t2.Dispose(); t3.Dispose(); underidx1.Dispose(); underidx2.Dispose(); underidx3.Dispose(); overidx1.Dispose(); overidx2.Dispose(); overidx3.Dispose(); var tSplit = t.Split(); t1 = tSplit[0]; t2 = tSplit[1]; t3 = tSplit[2]; var range1_1 = t1.ThresholdBinaryInv(new Gray(1.0 / 6), new Gray(1.0)); var range1_2 = t2.ThresholdBinaryInv(new Gray(1.0 / 6), new Gray(1.0)); var range1_3 = t3.ThresholdBinaryInv(new Gray(1.0 / 6), new Gray(1.0)); var range2_1 = t1.InRange(new Gray(1.0 / 6), new Gray(1.0 / 2)).Convert <Gray, float>() / 255.0; var range2_2 = t2.InRange(new Gray(1.0 / 6), new Gray(1.0 / 2)).Convert <Gray, float>() / 255.0; var range2_3 = t3.InRange(new Gray(1.0 / 6), new Gray(1.0 / 2)).Convert <Gray, float>() / 255.0; var range3_1 = t1.InRange(new Gray(1.0 / 2), new Gray(2.0 / 3)).Convert <Gray, float>() / 255.0; var range3_2 = t2.InRange(new Gray(1.0 / 2), new Gray(2.0 / 3)).Convert <Gray, float>() / 255.0; var range3_3 = t3.InRange(new Gray(1.0 / 2), new Gray(2.0 / 3)).Convert <Gray, float>() / 255.0; var range4_1 = t1.ThresholdBinary(new Gray(2.0 / 3), new Gray(1.0)); var range4_2 = t2.ThresholdBinary(new Gray(2.0 / 3), new Gray(1.0)); var range4_3 = t3.ThresholdBinary(new Gray(2.0 / 3), new Gray(1.0)); var range1 = new Image <Bgr, float>(new Image <Gray, float>[] { range1_1, range1_2, range1_3 }); var range2 = new Image <Bgr, float>(new Image <Gray, float>[] { range2_1, range2_2, range2_3 }); var range3 = new Image <Bgr, float>(new Image <Gray, float>[] { range3_1, range3_2, range3_3 }); var range4 = new Image <Bgr, float>(new Image <Gray, float>[] { range4_1, range4_2, range4_3 }); underidx.Dispose(); underidx1.Dispose(); underidx2.Dispose(); underidx3.Dispose(); overidx.Dispose(); overidx1.Dispose(); overidx2.Dispose(); overidx3.Dispose(); t1.Dispose(); t2.Dispose(); t3.Dispose(); range1_1.Dispose(); range1_2.Dispose(); range1_3.Dispose(); range2_1.Dispose(); range2_2.Dispose(); range2_3.Dispose(); range3_1.Dispose(); range3_2.Dispose(); range3_3.Dispose(); range4_1.Dispose(); range4_2.Dispose(); range4_3.Dispose(); var P = new Image <Bgr, float>(new Image <Gray, float>[] { p, p, p }); var Q = new Image <Bgr, float>(new Image <Gray, float>[] { q, q, q }); var rgb_c = (P + ((6 * (Q - P)).Mul(t))).Mul(range1) + Q.Mul(range2) + (P + (((Q - P) * 6).Mul(2 / 3 - t))).Mul(range3) + P.Mul(range4); rgb_c *= 255.0; P.Dispose(); Q.Dispose(); p.Dispose(); q.Dispose(); t.Dispose(); var rgb_cShape = new Image <Bgr, float>(bgrimage.Cols, bgrimage.Rows); MatHelper.CopyTo(ref rgb_c, 0, 0, rgb_c.Cols, rgb_c.Rows, ref rgb_cShape, 0, 0, rgb_cShape.Cols, rgb_cShape.Rows); //var H = hsv.Split()[0]; ////MatHelper.CopyTo(ref hsplit0, 0, 0, hsplit0.Cols, hsplit0.Rows, ref H, 0, 0, H.Cols, H.Rows); //var L_shape = new Image<Gray, float>(bgrimage.Cols, bgrimage.Rows); //var S_shape = new Image<Gray, float>(bgrimage.Cols, bgrimage.Rows); //MatHelper.CopyTo(ref S, 0, 0, S.Cols, S.Rows, ref S_shape, 0, 0, S_shape.Cols, S_shape.Rows); //MatHelper.CopyTo(ref L, 0, 0, L.Cols, L.Rows, ref L_shape, 0, 0, L_shape.Cols, L_shape.Rows); return(rgb_cShape.Convert <Bgr, byte>()); }
public static Image <Bgr, byte> Bgr2Hsl(Image <Bgr, byte> bgrimage) { var doubleBgr = bgrimage.Convert <Bgr, float>() / 255; var numPoints = bgrimage.Rows * bgrimage.Cols; var bgrDoubleReshaped = new Image <Gray, float>(3, numPoints); var channels = doubleBgr.Split(); MatHelper.CopyTo(ref channels[0], 0, 0, channels[0].Cols, channels[0].Rows, ref bgrDoubleReshaped, 0, 0, 1, numPoints); MatHelper.CopyTo(ref channels[1], 0, 0, channels[1].Cols, channels[1].Rows, ref bgrDoubleReshaped, 1, 0, 1, numPoints); MatHelper.CopyTo(ref channels[2], 0, 0, channels[2].Cols, channels[2].Rows, ref bgrDoubleReshaped, 2, 0, 1, numPoints); var mx = MatHelper.maxInLines(bgrDoubleReshaped); var mn = MatHelper.minInLines(bgrDoubleReshaped); Mat nonzeroidx = new Mat(mx.Rows, mx.Cols, Emgu.CV.CvEnum.DepthType.Cv8U, mx.NumberOfChannels); Mat zeroidx = new Mat(mx.Rows, mx.Cols, Emgu.CV.CvEnum.DepthType.Cv8U, mx.NumberOfChannels); var L = (mx + mn) / 2; var S = new Image <Gray, float>(L.Size); CvInvoke.Compare(mx, mn, zeroidx, Emgu.CV.CvEnum.CmpType.Equal); CvInvoke.BitwiseNot(zeroidx, nonzeroidx); Mat lowlidx = new Mat(mx.Rows, mx.Cols, Emgu.CV.CvEnum.DepthType.Cv8U, mx.NumberOfChannels); var calc = new Image <Gray, float>(mx.Size); var mmsum = mx + mn; var mmsub = mx - mn; var auxImage = new Image <Gray, float>(L.Size); auxImage.SetValue(new Gray(0.5)); ////CvInvoke.Threshold(L, lowlidx, 0.5, 1.0, Emgu.CV.CvEnum.ThresholdType.BinaryInv); CvInvoke.Compare(L, auxImage, lowlidx, Emgu.CV.CvEnum.CmpType.LessEqual); //CvInvoke.Divide(mmsub, mmsum, calc); calc = mmsub.Mul(1.0 / mmsum); Mat idx = new Mat(); CvInvoke.BitwiseAnd(lowlidx, nonzeroidx, idx); calc.Mat.CopyTo(S, idx); Mat hilidx = new Mat(mx.Rows, mx.Cols, Emgu.CV.CvEnum.DepthType.Cv8U, mx.NumberOfChannels); CvInvoke.Compare(L, auxImage, hilidx, Emgu.CV.CvEnum.CmpType.GreaterThan); var mmsum2 = (2 - (mx + mn)); calc = mmsub.Mul(1.0 / mmsum2); CvInvoke.BitwiseAnd(hilidx, nonzeroidx, idx); calc.Mat.CopyTo(S, idx); //var hsv = doubleBgr.Convert<Hsv, float>() / 255; var hsv = Bgr2Hsv(bgrDoubleReshaped); var H = hsv.Split()[2]; //MatHelper.CopyTo(ref hsplit0, 0, 0, hsplit0.Cols, hsplit0.Rows, ref H, 0, 0, H.Cols, H.Rows); var L_shape = new Image <Gray, float>(bgrimage.Cols, bgrimage.Rows); var S_shape = new Image <Gray, float>(bgrimage.Cols, bgrimage.Rows); var H_shape = new Image <Gray, float>(bgrimage.Cols, bgrimage.Rows); MatHelper.CopyTo(ref S, 0, 0, S.Cols, S.Rows, ref S_shape, 0, 0, S_shape.Cols, S_shape.Rows); MatHelper.CopyTo(ref L, 0, 0, L.Cols, L.Rows, ref L_shape, 0, 0, L_shape.Cols, L_shape.Rows); MatHelper.CopyTo(ref H, 0, 0, H.Cols, H.Rows, ref H_shape, 0, 0, H_shape.Cols, H_shape.Rows); CvInvoke.Transpose(H_shape, H_shape); CvInvoke.Transpose(S_shape, S_shape); CvInvoke.Transpose(L_shape, L_shape); var hsl = new Image <Bgr, float>(new Image <Gray, float>[] { L_shape, S_shape, H_shape }); hsl *= 255; return(hsl.Convert <Bgr, byte>()); }
private void processVideo(object sender, DoWorkEventArgs e) { CvInvoke.UseOpenCL = true; CvInvoke.UseOptimized = true; //determine amount of maps already present in the world int mapCount = 0; NbtFile map = null; try { map = new NbtFile(Path.Join(WorldFolderPath, "\\data\\idcounts.dat")); mapCount = Int32.Parse(map.RootTag.Get <NbtCompound>("data").Get <NbtInt>("map").Value.ToString()) + 1; } catch { } Debug.Write("MapCount:" + mapCount + "\n"); //start videocapture VideoCapture video = new VideoCapture(VideoFilePath); //get framerate framerate = video.GetCaptureProperty(CapProp.Fps); //get framecount frames = video.GetCaptureProperty(CapProp.FrameCount); //calculate allFrames at the target framerate reducedFrames = Math.Floor((frames / framerate) * TargetFrameRate); if (map != null) { map.RootTag.Get <NbtCompound>("data").Get <NbtInt>("map").Value = mapCount + ((int)reducedFrames) * 15; map.SaveToFile(Path.Join(WorldFolderPath, "\\data\\idcounts.dat"), NbtCompression.None); } //create Preset for map data NbtCompound preset = new NbtCompound("") { new NbtCompound("data") { new NbtString("dimension", "minecraft:overworld"), new NbtLong("xCenter", 128), new NbtLong("zCenter", 128), new NbtByte("scale", 3), new NbtByte("locked", 1), new NbtByte("unlimitedTracking", 0), new NbtByte("trackingPosition", 0), new NbtByteArray("colors") }, new NbtInt("DataVersion", 2584) }; //create path to output folder string mapOutputFolder = Path.Join(WorldFolderPath, "/data"); UMat ones = new UMat(1, 3, DepthType.Cv8U, 1, UMat.Usage.AllocateDeviceMemory); ones.SetTo(new MCvScalar(1)); UMat calculation = new UMat(new Size(640, 384), DepthType.Cv32S, 3, UMat.Usage.AllocateDeviceMemory); UMat singleChannel = new UMat(new Size(640, 384), DepthType.Cv32S, 1, UMat.Usage.AllocateDeviceMemory); //keeps lowest value UMat lowestDiversion = new UMat(new Size(640, 384), DepthType.Cv32S, 1, UMat.Usage.AllocateDeviceMemory); //bool UMat lessDiversion = new UMat(new Size(640, 384), DepthType.Cv8U, 1, UMat.Usage.AllocateDeviceMemory); //store block value UMat blocks = new UMat(new Size(640, 384), DepthType.Cv8U, 1, UMat.Usage.AllocateDeviceMemory); while (frame < reducedFrames) { //calculate position in video and set to next frame position = frame / reducedFrames; video.SetCaptureProperty(CapProp.PosFrames, Math.Round(position * frames)); var watch = System.Diagnostics.Stopwatch.StartNew(); //get video frame if (!video.Read(singleFrame)) { break; } //resize to minecraft compatible resolution CvInvoke.Resize(singleFrame, singleFrame, new Size(640, 384)); singleFrame.ConvertTo(singleFrame, DepthType.Cv32F); //display current Frame to user if (PreviewPicture.Image != null) { PreviewPicture.Image.Dispose(); } PreviewPicture.Image = singleFrame.ToBitmap(); lowestDiversion.SetTo(new MCvScalar(255)); lessDiversion.SetTo(new MCvScalar(0)); blocks.SetTo(Colors.minecraftColors[Colors.minecraftColors.Length - 1]); for (int i = 0; i < Colors.minecraftColors.Length; i++) { calculation = singleFrame - Colors.minecraftColors[i]; CvInvoke.Multiply(calculation, calculation, calculation); CvInvoke.Transform(calculation, singleChannel, ones); CvInvoke.Sqrt(singleChannel, singleChannel); singleChannel.ConvertTo(singleChannel, DepthType.Cv32S); CvInvoke.Compare(singleChannel, lowestDiversion, lessDiversion, CmpType.LessThan); singleChannel.CopyTo(lowestDiversion, lessDiversion); blocks.SetTo(new MCvScalar(i + 4), lessDiversion); } for (int y = 0; y < 3; y++) { for (int x = 0; x < 5; x++) { UMat output = new UMat(blocks, new Rectangle(128 * x, 128 * y, 128, 128)); preset.Get <NbtCompound>("data").Get <NbtByteArray>("colors").Value = output.Bytes; NbtFile file = new NbtFile(preset); file.SaveToFile(Path.Join(mapOutputFolder, String.Concat("map_", mapCount + (frame * 15) + (y * 5 + x), ".dat")), NbtCompression.None); } } watch.Stop(); elapsedTime = watch.ElapsedMilliseconds; Debug.Write("Took:" + elapsedTime + "\n"); System.GC.Collect(); //send progress update to ui and console worker.ReportProgress((int)Math.Round(position * 100), elapsedTime * (reducedFrames - frame)); Debug.Write(frame + "/" + reducedFrames + "-" + position + "\n"); //increase framecount frame++; } worker.ReportProgress(100, 0.0); //pass the values to display to the user e.Result = new convertResult((int)frame - 1, mapCount); }