/// <summary> /// draw overlay(has transparent background ) on bg /// </summary> /// <param name="bg"></param> /// <param name="overlay"></param> public unsafe static void DrawOverlay(Mat bg, Mat overlay) { if (bg.Size() != overlay.Size()) { throw new System.ArgumentException("bg.Size()!=overlay.Size()"); } if (overlay.Channels() < 4) { throw new System.ArgumentException("overlay.Channels()<4"); } int colsOverlay = overlay.Cols; int rowsOverlay = overlay.Rows; //https://stackoverflow.com/questions/54069766/overlaying-an-image-over-another-image-both-with-transparent-background-using-op for (int i = 0; i < rowsOverlay; i++) { Vec3b *pBg = (Vec3b *)bg.Ptr(i); Vec4b *pOverlay = (Vec4b *)overlay.Ptr(i); for (int j = 0; j < colsOverlay; j++) { Vec3b *pointBg = pBg + j; Vec4b *pointOverlay = pOverlay + j; if (pointOverlay->Item3 != 0) { pointBg->Item0 = pointOverlay->Item0; pointBg->Item1 = pointOverlay->Item1; pointBg->Item2 = pointOverlay->Item2; } } } }
unsafe void OpVec3b(Vec3b *bt, int *pos) { byte r, g, b; r = (*bt).Item2; g = (*bt).Item1; b = (*bt).Item0; //if ( r> 80 && g > 80 && b > 80) { itemcnt++; item0 += r; item1 += g; item2 += b; } }
/// <summary> /// Render matMask by src, every green pixel on src will cause a black pixel rendered on the same position on matMask, /// otherwise, a white pixel will be rendered on matMask /// </summary> /// <param name="src"></param> /// <param name="matMask"></param> private unsafe void RenderGreenScreenMask(Mat src, Mat matMask) { if (src.Channels() < 3) { throw new ArgumentException("src.Channels() should >=3"); } if (matMask.Channels() != 1) { throw new ArgumentException("matMask.Channels() should == 1"); } if (src.Size() != matMask.Size()) { throw new System.ArgumentException("src.Size()!=matMask.Size()"); } //https://codereview.stackexchange.com/questions/184044/processing-an-image-to-extract-green-screen-mask int rows = src.Rows; int cols = src.Cols; for (int x = 0; x < rows; x++) { Vec3b *srcRow = (Vec3b *)src.Ptr(x); byte * maskRow = (byte *)matMask.Ptr(x); for (int y = 0; y < cols; y++) { var pData = srcRow + y; byte blue = pData->Item0; byte green = pData->Item1; byte red = pData->Item2; byte max1 = blue > green ? blue : green; byte max = max1 > red?max1:red; //if this pixel is some green, render the pixel with the same position on matMask as black if (green == max && green > this._greenScale) { *(maskRow + y) = 0; } else { *(maskRow + y) = 255;//render as white } } } }
public static extern unsafe int core_Mat_nGetVec3b(IntPtr obj, int row, int col, Vec3b *vals, int valsLength);
private static unsafe void ReverseHue(Vec3b *value, int *position) { var bgr = (value->Item0 / 255f, value->Item1 / 255f, value->Item2 / 255f); var max = Math.Max(bgr.Item1, Math.Max(bgr.Item2, bgr.Item3)); var min = Math.Min(bgr.Item1, Math.Min(bgr.Item2, bgr.Item3)); var hsv = (double.NaN, double.NaN, double.NaN); hsv.Item2 = max - (double)min; hsv.Item3 = max; if (max == min) { hsv.Item1 = 0f; } else if (min == bgr.Item1) { hsv.Item1 = 60d * (bgr.Item2 - bgr.Item3) / hsv.Item2 + 60d; } else if (min == bgr.Item3) { hsv.Item1 = 60 * (bgr.Item1 - bgr.Item2) / hsv.Item2 + 180; } else if (min == bgr.Item2) { hsv.Item1 = 60 * (bgr.Item3 - bgr.Item1) / hsv.Item2 + 300; } hsv.Item1 = (hsv.Item1 + 180) % 360; var Hd = hsv.Item1 / 60d; var C = hsv.Item2; var X = C * (1 - Math.Abs((Hd % 2) - 1)); var rgb = (hsv.Item3 - C, hsv.Item3 - C, hsv.Item3 - C); if (Hd < 1) { rgb.Item1 += C; rgb.Item2 += X; } else if (Hd < 2) { rgb.Item1 += X; rgb.Item2 += C; } else if (Hd < 3) { rgb.Item2 += C; rgb.Item3 += X; } else if (Hd < 4) { rgb.Item2 += X; rgb.Item3 += C; } else if (Hd < 5) { rgb.Item1 += X; rgb.Item3 += C; } else if (Hd < 6) { rgb.Item1 += C; rgb.Item3 += X; } value->Item0 = (byte)(rgb.Item3 * 255); value->Item1 = (byte)(rgb.Item2 * 255); value->Item2 = (byte)(rgb.Item1 * 255); }
private static unsafe void DecreaseColor(Vec3b *value, int *position) {