public static Point[] FindSameAll(this Mat src, Mat trg, Vec3b bg) { var rst = new List <Point>(); var trgIdxr = (new MatOfByte3(trg)).GetIndexer(); src.Slide(trg.Size(), (Mat sbj, Point point) => { var sbjIdxr = (new MatOfByte3(sbj)).GetIndexer(); for (int y = 0; y < sbj.Height; y++) { for (int x = 0; x < sbj.Width; x++) { var trgVec = trgIdxr[y, x]; if (trgVec == bg) { continue; } var sbjVec = sbjIdxr[y, x]; if (sbjVec != trgVec) { return; } } } rst.Add(point); }); return(rst.ToArray()); }
private static void LineIterator() { var img = new Mat("data/lenna.png", ImreadModes.Color); var pt1 = new Point(100, 100); var pt2 = new Point(300, 300); var iterator = new LineIterator(img, pt1, pt2, PixelConnectivity.Connectivity8); // invert color foreach (var pixel in iterator) { Vec3b value = pixel.GetValue <Vec3b>(); value.Item0 = (byte)~value.Item0; value.Item1 = (byte)~value.Item1; value.Item2 = (byte)~value.Item2; pixel.SetValue(value); } // re-enumeration works fine foreach (var pixel in iterator) { Vec3b value = pixel.GetValue <Vec3b>(); Console.WriteLine("{0} = ({1},{2},{3})", pixel.Pos, value.Item0, value.Item1, value.Item2); } Window.ShowImages(img); }
public static IList <BoundingBox> ObtainBoundingBoxes(string base64Image) { var opencvImage = Image.ConvertFromBase64ToMat(base64Image); var tensor = new DenseTensor <float>(new int[] { channels, opencvImage.Height, opencvImage.Width }); using (var mat = new MatOfByte3(opencvImage)) { var indexer = mat.GetIndexer(); for (int y = 0; y < opencvImage.Height; y++) { for (int x = 0; x < opencvImage.Width; x++) { Vec3b color = indexer[y, x]; tensor[0, y, x] = (float)color.Item2; tensor[1, y, x] = (float)color.Item1; tensor[2, y, x] = (float)color.Item0; } } } var transform = tensor.Reshape(new ReadOnlySpan <int>(new[] { channels *opencvImage.Height *opencvImage.Width })); var yoloParser = new YoloOutputParser(); var yoloModel = YoloModel.Instance; var results = yoloModel.Evaluate(new[] { transform }); return(yoloParser.ParseOutputs(results.First().ToArray())); }
private static Mat HistogramManipulation(Mat img, byte targetMean, byte targetStdDev) { img.GetArray(out Vec3b[] vec3bArray); var byteArray = vec3bArray.SelectMany(i => i.ToByteEnumerable()).ToArray(); var sourceMean = byteArray.Sum(i => i) / (double)byteArray.Length; var sourceStdDev = Math.Sqrt(byteArray.Sum(i => Math.Pow(i - sourceMean, 2)) / byteArray.Length); byte manipulation(byte chValue) { return((byte)(targetStdDev / sourceStdDev * (chValue - sourceMean) + targetMean)); } var outMat = Mat.Zeros(img.Rows, img.Cols, MatType.CV_8UC3).ToMat(); var outIndexer = outMat.GetGenericIndexer <Vec3b>(); var imgIndexer = img.GetGenericIndexer <Vec3b>(); for (int y = 0; y < img.Rows; y++) { for (int x = 0; x < img.Cols; x++) { var pixel = imgIndexer[y, x]; var newPixel = new Vec3b() { Item0 = manipulation(pixel.Item0), Item1 = manipulation(pixel.Item1), Item2 = manipulation(pixel.Item2), }; outIndexer[y, x] = newPixel; } } return(outMat); }
public SPoint(SPoint other) { X = other.X; Y = other.Y; Color = other.Color; LineWidth = other.LineWidth; }
/// <summary> /// 访问像素 /// </summary> public static void AccessPixel() { using (Mat mat = new Mat("Images/lena.jpg", ImreadModes.Color)) { //bgr格式 using (MatOfByte3 mat3 = new MatOfByte3(mat)) { var indexer = mat3.GetIndexer(); for (int y = 0; y < mat.Height; y++) { for (int x = 0; x < mat.Width; x++) { Vec3b color = indexer[y, x]; byte temp = color.Item0; color.Item0 = color.Item2;//B <-- R color.Item2 = temp; indexer[y, x] = color; } } } using (new Window("window", mat)) { Cv2.WaitKey(); } } }
private static void usingCppInterface1() { // Cv2.ImRead using (var src = new Mat(@"..\..\Images\Penguin.Png", LoadMode.AnyDepth | LoadMode.AnyColor)) using (var dst = new Mat()) { src.CopyTo(dst); for (var y = 0; y < src.Height; y++) { for (var x = 0; x < src.Width; x++) { var pixel = src.Get <Vec3b>(y, x); var newPixel = new Vec3b { Item0 = (byte)(255 - pixel.Item0), // B Item1 = (byte)(255 - pixel.Item1), // G Item2 = (byte)(255 - pixel.Item2) // R }; dst.Set(y, x, newPixel); } } // [Cpp] Accessing Pixel // https://github.com/shimat/opencvsharp/wiki/%5BCpp%5D-Accessing-Pixel //Cv2.NamedWindow(); //Cv2.ImShow(); using (new Window("C++ Interface: Src", image: src)) using (new Window("C++ Interface: Dst", image: dst)) { Cv2.WaitKey(0); } } }
private static void usingCppInterface1() { // Cv2.ImRead using (var src = new Mat(@"..\..\Images\Penguin.Png", LoadMode.AnyDepth | LoadMode.AnyColor)) using (var dst = new Mat()) { src.CopyTo(dst); for (var y = 0; y < src.Height; y++) { for (var x = 0; x < src.Width; x++) { var pixel = src.Get<Vec3b>(y, x); var newPixel = new Vec3b { Item0 = (byte)(255 - pixel.Item0), // B Item1 = (byte)(255 - pixel.Item1), // G Item2 = (byte)(255 - pixel.Item2) // R }; dst.Set(y, x, newPixel); } } // [Cpp] Accessing Pixel // https://github.com/shimat/opencvsharp/wiki/%5BCpp%5D-Accessing-Pixel //Cv2.NamedWindow(); //Cv2.ImShow(); using (new Window("C++ Interface: Src", image: src)) using (new Window("C++ Interface: Dst", image: dst)) { Cv2.WaitKey(0); } } }
public void コントラスト調整(ref Mat src, double 率) { int width = src.Width; int height = src.Height; var indexer = new MatOfByte3(src).GetIndexer(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Vec3b color = indexer[y, x]; double val = color.Item0 * 率; if (val > 255) { color.Item0 = 255; } else if (val < 0) { color.Item0 = 0; } else { color.Item0 = (byte)val; } indexer[y, x] = color; } } indexer = null; }
//! [scan-iterator] //! [scan-random] public static Mat ScanImageAndReduceRandomAccess(Mat I, byte[] table) { int channels = I.Channels(); switch (channels) { case 1: for (int i = 0; i < I.Rows; ++i) { for (int j = 0; j < I.Cols; ++j) { I.Set(i, j, table[I.At <byte>(i, j)]); } } break; case 3: for (int i = 0; i < I.Rows; ++i) { for (int j = 0; j < I.Cols; ++j) { Vec3b v = I.Get <Vec3b>(i, j); v.Item0 = table[v.Item0]; v.Item1 = table[v.Item1]; v.Item2 = table[v.Item2]; I.Set <Vec3b>(i, j, v); } } break; } return(I); }
public SPoint(int x, int y, Vec3b color, int lineWidth = 1) { X = x; Y = y; Color = color; LineWidth = lineWidth; }
//指数变换 public static Mat IndexTransform(Mat source) { Mat result = new Mat(source.Size(), source.Type()); int rows = source.Rows; int cols = source.Cols; double k = 1 / 255f; for (int rowIndex = 0; rowIndex < rows; rowIndex++) { for (int colIndex = 0; colIndex < cols; colIndex++) { Vec3b color = source.At <Vec3b>(rowIndex, colIndex); byte B = color[0]; byte G = color[1]; byte R = color[2]; B = (byte)(k * B * B); G = (byte)(k * G * G); R = (byte)(k * R * R); color = new Vec3b(B, G, R); result.Set <Vec3b>(rowIndex, colIndex, color); } } return(result); }
public static IList <YoloBoundingBox> ObtainBoundingBoxes(string base64Image) { var opencvImage = Image.ConvertFromBase64ToMat(base64Image); MatOfByte3 mat3 = new MatOfByte3(opencvImage); var indexer = mat3.GetIndexer(); Tensor <float> imageData = new DenseTensor <float>(new[] { 3, opencvImage.Width, opencvImage.Height }); for (int y = 0; y < opencvImage.Height; y++) { for (int x = 0; x < opencvImage.Width; x++) { Vec3b color = indexer[y, x]; imageData[0, y, x] = (float)color.Item2; imageData[1, y, x] = (float)color.Item1; imageData[2, y, x] = (float)color.Item0; } } var yoloParser = new YoloParser(); var resultTransform = imageData.Reshape(new ReadOnlySpan <int>(new[] { 3 * 416 * 416 })); var yoloModel = new YoloModel(); var results = yoloModel.Evaluate(new[] { resultTransform }); var boundingBoxes = yoloParser.ParseOutputs(results.First().ToArray()); return(boundingBoxes); }
private void MatToTexture() { int width = 1147; int height = 557; // Create Color32 array that can be assigned to Texture2D directly Color32[] c = new Color32[width * height]; // Parallel for loop for (int i = 0; i < height; i++) { for (var j = 0; j < width; j++) { Vec3b vec = _imageData[j + i * width]; var color32 = new Color32 { r = vec[0], g = vec[1], b = vec[2], a = 0 }; c[j + i * width] = color32; } } _texture.SetPixels32(c); // Update the texture, OpenGL manner _texture.Apply(); }
//蓝红颜色互换 private void BtnChange1_Click(object sender, RoutedEventArgs e) { Mat mat = new Mat(@"..\..\Images\ocv01.jpg", ImreadModes.Unchanged); //Mat mat = new Mat(new OpenCvSharp.Size(128, 128), MatType.CV_8U, Scalar.All(255)); for (var y = 0; y < mat.Height; y++) { for (var x = 0; x < mat.Width; x++) { Vec3b color = mat.Get <Vec3b>(y, x); var temp = color.Item0; color.Item0 = color.Item2; // B <- R color.Item2 = temp; // R <- B mat.Set(y, x, color); } } var mem = mat.ToMemoryStream(); BitmapImage bmp = new BitmapImage(); bmp.BeginInit(); bmp.StreamSource = mem; bmp.EndInit(); imgOutput.Source = bmp; mat.Dispose();/// 该方法在mat里被重写了,可以释放资源,可以放心调用 SetSource(@"..\..\Images\ocv01.jpg"); }
void CalculateHairColor() { int hairCompteur = 0; float hairRedColorAverage = 0f; float hairGreenColorAverage = 0f; float hairBlueColorAverage = 0f; // parallel for loop Parallel.For(0, imHeight, i => { for (var j = 0; j < imWidth; j++) { float coordX = j; float coordY = imHeight - i; Vec3b vec = videoSourceImageData[j + i * imWidth]; if (coordX > rectCheveux.X && coordX < rectCheveux.X + rectCheveux.Width && coordY > rectCheveux.Y && coordY < rectCheveux.Y + rectCheveux.Height) { hairCompteur++; hairRedColorAverage += vec.Item2; hairGreenColorAverage += vec.Item1; hairBlueColorAverage += vec.Item0; } } }); // hair color hairRedColorAverage = hairRedColorAverage / hairCompteur; hairGreenColorAverage = hairGreenColorAverage / hairCompteur; hairBlueColorAverage = hairBlueColorAverage / hairCompteur; couleurCheveux = new Vec3f(hairRedColorAverage, hairGreenColorAverage, hairBlueColorAverage); Debug.Log(hairCompteur); }
private Vec3b[] TextureToMat(Texture2D texture) { var width = texture.width; var height = texture.height; // Color32 array : r, g, b, a Color32[] c = texture.GetPixels32(); // Convert Color32 object to Vec3b object // Vec3b is the representation of pixel for Mat for (int i = 0; i < height; i++) { for (var j = 0; j < width; j++) { var col = c[j + i * width]; var vec3 = new Vec3b { Item0 = col.b, Item1 = col.g, Item2 = col.r }; // set pixel to an array _imageData[j + i * width] = vec3; } } return(_imageData); }
/// <summary> /// Check that the specified color is not a lane /// </summary> static bool isBadColor(Vec3b color_t) { RGB rgb_color = new RGB(color_t[2], color_t[1], color_t[0]); HSV hsv_color = RGB.ToHSV(rgb_color); return(hsv_color.V > 0.85 || hsv_color.S > 0.94); }
public void RectangleFilled() { var color = Scalar.Red; using Mat img = Mat.Zeros(100, 100, MatType.CV_8UC3); img.Rectangle(new Rect(10, 10, 80, 80), color, Cv2.FILLED /*-1*/); if (Debugger.IsAttached) { Window.ShowImages(img); } var colorVec = color.ToVec3b(); var expected = new Vec3b[100, 100]; for (int y = 10; y < 90; y++) { for (int x = 10; x < 90; x++) { expected[y, x] = colorVec; } } TestImage(img, expected); }
public Scalar getColor() { if (average.Val0 != -1) { return(average); } MatOfByte3 mat3 = new MatOfByte3(data); var indexer = mat3.GetIndexer(); ArrayList hue = new ArrayList(); ArrayList light = new ArrayList(); ArrayList sat = new ArrayList(); for (int y = 0; y < data.Height; y++) { for (int x = 0; x < data.Width; x++) { Vec3b color = indexer[y, x]; hue.Add(color.Item0); light.Add(color.Item1); sat.Add(color.Item2); } } byte medHue = getMedian(hue); byte medLight = getMedian(light); byte medSat = getMedian(sat); average = new Scalar(medHue, medLight, medSat); return(average); }
//对数变换 public static Mat LogTransform(Mat source) { Mat result = new Mat(source.Size(), source.Type()); int rows = source.Rows; int cols = source.Cols; double k = 255 / Math.Log10(256.0); for (int rowIndex = 0; rowIndex < rows; rowIndex++) { for (int colIndex = 0; colIndex < cols; colIndex++) { Vec3b color = source.At <Vec3b>(rowIndex, colIndex); byte B = color[0]; byte G = color[1]; byte R = color[2]; B = (byte)(k * Math.Log10(B + 1)); G = (byte)(k * Math.Log10(G + 1)); R = (byte)(k * Math.Log10(R + 1)); color = new Vec3b(B, G, R); result.Set <Vec3b>(rowIndex, colIndex, color); } } return(result); }
private static NDArray MatToNdarray <T>(Mat mat) where T : struct { switch (typeof(T).Name) { case "Byte": { var data = new Vec3b[mat.Total()]; //mat.GetArray(0, 0, data); return(Vec3bToNdarray(data, mat.Height, mat.Width, mat.Channels())); } case "Int32": unsafe { var data = new Vec3i[mat.Total()]; mat.ForEachAsVec3i((value, position) => data[*position] = *value); return(Vec3iToNdarray(data, mat.Height, mat.Width, mat.Channels())); } case "Single": unsafe { var data = new Vec3d[mat.Total()]; //mat.GetArray(0, 0, data); throw new NotImplementedException(""); } default: throw new NotImplementedException(""); } }
// Convert Unity Texture2D object to OpenCVSharp Mat object void TextureToMat() { // Color32 array : r, g, b, a Color32[] c = _webcamTexture.GetPixels32(); // Parallel for loop // convert Color32 object to Vec3b object // Vec3b is the representation of pixel for Mat Parallel.For(0, imHeight, i => { for (var j = 0; j < imWidth; j++) { var col = c[j + i * imWidth]; var vec3 = new Vec3b { Item0 = col.b, Item1 = col.g, Item2 = col.r }; // set pixel to an array videoSourceImageData[j + i * imWidth] = vec3; } }); // assign the Vec3b array to Mat videoSourceImage.SetArray(0, 0, videoSourceImageData); }
public void Rectangle() { var color = Scalar.Red; using (Mat img = Mat.Zeros(100, 100, MatType.CV_8UC3)) { img.Rectangle(new Rect(10, 10, 80, 80), color, 1); ShowImagesWhenDebugMode(img); var colorVec = color.ToVec3b(); var expected = new Vec3b[100, 100]; for (int x = 10; x < 90; x++) { expected[10, x] = colorVec; expected[89, x] = colorVec; } for (int y = 10; y < 90; y++) { expected[y, 10] = colorVec; expected[y, 89] = colorVec; } TestImage(img, expected); } }
/// <summary>Создание маски для отсечения помех</summary> /// <param name="roi"> ROI</param> /// <param name="lines"> Линии ROI</param> /// <returns>Матрица-маска</returns> private Mat CreateMask(ref Mat roi, float[][] lines) { var mask = Mat.Zeros(roi.Size(), MatType.CV_8UC1).ToMat(); var roiVecInd = mask.GetGenericIndexer <Vec3b>(); for (var i = 0; i < roi.Height; i++) { for (var j = 0; j < roi.Width; j++) { var inside = true; //Проходит по всем линиям for (var k = 0; k < lines.Length; k++) { //Проверяет все точки Roi на наличие их в Plane var tmp2 = CheckDot(j, i, lines[k]); if (tmp2 <= 0) { inside = false; break; } } if (inside) { roiVecInd[i, j] = new Vec3b(255, 255, 255); } } } return(mask); }
public static Vec3b RoundVec3b(Vec3b src, int steps) { src.Item0 = (byte)(int)RoundDouble(src.Item0, 256, steps, 255); src.Item1 = (byte)(int)RoundDouble(src.Item1, 256, steps, 255); src.Item2 = (byte)(int)RoundDouble(src.Item2, 256, steps, 255); return(src); }
private static IEnumerable <byte> ToByteEnumerable(this Vec3b item) { yield return(item.Item0); yield return(item.Item1); yield return(item.Item2); }
private static Mat GaussianFiliter(Mat img, int kernelSize, double stdDev) { var outMat = Mat.Zeros(img.Rows, img.Height, MatType.CV_8UC3).ToMat(); var kernel = new double[kernelSize, kernelSize]; var pad = kernelSize / 2; var kernelSum = 0d; for (int y = 0; y < kernelSize; y++) { for (int x = 0; x < kernelSize; x++) { var _y = y - pad; var _x = x - pad; kernel[y, x] = 1 / (2 * Math.PI * stdDev * stdDev) * Math.Exp(-(_x * _x + _y * _y) / (2 * stdDev * stdDev)); kernelSum += kernel[y, x]; } } for (int y = 0; y < kernelSize; y++) { for (int x = 0; x < kernelSize; x++) { kernel[y, x] /= kernelSum; } } double b, g, r; var imgIndexer = img.GetGenericIndexer <Vec3b>(); var outIndexer = outMat.GetGenericIndexer <Vec3b>(); for (int y = 0; y < img.Height; y++) { for (int x = 0; x < img.Cols; x++) { b = g = r = 0d; for (int dy = -pad; dy < pad + 1; dy++) { for (int dx = -pad; dx < pad + 1; dx++) { if ((x + dx < 0) || (y + dy < 0)) { continue; } var pixel = imgIndexer[y + dy, x + dx]; b += pixel.Item0 * kernel[dy + pad, dx + pad]; g += pixel.Item1 * kernel[dy + pad, dx + pad]; r += pixel.Item2 * kernel[dy + pad, dx + pad]; } } outIndexer[y, x] = new Vec3b((byte)b, (byte)g, (byte)r); } } return(outMat); }
private static Mat HistogramNormalization(Mat img, byte targetMin, byte targetMax) { var outMat = Mat.Zeros(img.Rows, img.Cols, MatType.CV_8UC3).ToMat(); var sourceMin = targetMax; var sourceMax = targetMin; void minMax(byte t) { sourceMax = Math.Max(t, sourceMax); sourceMin = Math.Min(t, sourceMin); } var imgIndexer = img.GetGenericIndexer <Vec3b>(); for (int y = 0; y < img.Rows; y++) { for (int x = 0; x < img.Cols; x++) { var pixel = imgIndexer[y, x]; minMax(pixel.Item0); minMax(pixel.Item1); minMax(pixel.Item2); } } byte transformation(byte chValue) { if (chValue < targetMin) { return(targetMin); } if (chValue <= targetMax) { return((byte)((targetMax - targetMin) / (sourceMax - sourceMin) * (chValue - sourceMin) + targetMin)); } return(targetMax); } var outIndexer = outMat.GetGenericIndexer <Vec3b>(); for (int y = 0; y < img.Rows; y++) { for (int x = 0; x < img.Cols; x++) { var pixel = imgIndexer[y, x]; var newPixel = new Vec3b() { Item0 = transformation(pixel.Item0), Item1 = transformation(pixel.Item1), Item2 = transformation(pixel.Item2), }; outIndexer[y, x] = newPixel; } } return(outMat); }
public void NormVecb() { var vec = new Vec3b(10, 20, 30); using var ia = InputArray.Create(vec); var norm = Cv2.Norm(ia, NormTypes.L1); Assert.Equal(60, norm); }
static bool isBlack(Vec3b c) { if (c.Item0 + c.Item1 + c.Item2 < 10) { return(true); } return(false); }
private static void example02() { var src = new Mat(@"..\..\Images\fruits.jpg", LoadMode.AnyDepth | LoadMode.AnyColor); Cv2.ImShow("Source", src); Cv2.WaitKey(1); // do events Cv2.Blur(src, src, new Size(15, 15)); Cv2.ImShow("Blurred Image", src); Cv2.WaitKey(1); // do events // Converts the MxNx3 image into a Kx3 matrix where K=MxN and // each row is now a vector in the 3-D space of RGB. // change to a Mx3 column vector (M is number of pixels in image) var columnVector = src.Reshape(cn: 3, rows: src.Rows * src.Cols); // convert to floating point, it is a requirement of the k-means method of OpenCV. var samples = new Mat(); columnVector.ConvertTo(samples, MatType.CV_32FC3); for (var clustersCount = 2; clustersCount <= 8; clustersCount += 2) { var bestLabels = new Mat(); var centers = new Mat(); Cv2.Kmeans( data: samples, k: clustersCount, bestLabels: bestLabels, criteria: new TermCriteria(type: CriteriaType.Epsilon | CriteriaType.Iteration, maxCount: 10, epsilon: 1.0), attempts: 3, flags: KMeansFlag.PpCenters, centers: centers); var clusteredImage = new Mat(src.Rows, src.Cols, src.Type()); for (var size = 0; size < src.Cols * src.Rows; size++) { var clusterIndex = bestLabels.At<int>(0, size); var newPixel = new Vec3b { Item0 = (byte)(centers.At<float>(clusterIndex, 0)), // B Item1 = (byte)(centers.At<float>(clusterIndex, 1)), // G Item2 = (byte)(centers.At<float>(clusterIndex, 2)) // R }; clusteredImage.Set(size / src.Cols, size % src.Cols, newPixel); } Cv2.ImShow(string.Format("Clustered Image [k:{0}]", clustersCount), clusteredImage); Cv2.WaitKey(1); // do events } Cv2.WaitKey(); Cv2.DestroyAllWindows(); }
public static extern void core_Mat_push_back_Vec3b(IntPtr self, Vec3b v);
public void 吉岡反射光除去処理(Mat[] images, ref Mat DST,int th_l,int th_h) { int width = images[0].Width; int height = images[0].Height; MatIndexer<Vec3b>[] indexers = new MatIndexer<Vec3b>[4]; var indexer = new MatOfByte3(DST).GetIndexer(); for (int i = 0; i < 4; i++) indexers[i] = new MatOfByte3(images[i]).GetIndexer(); for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) {//medianX,Y SG完成 Vec3b[] colors = new Vec3b[4]; Vec3b color = indexer[y, x]; for (int i = 0; i < 4; i++) colors[i] = indexers[i][y, x]; double[] vals = { 0, 0, 0, 0 }; for (int num = 0; num < 4; num++) vals[num] = colors[num].Item0; Array.Sort(vals);//並び替えを行う.min=vals[0] for (int i = 1; i < 3; i++) { //if (vals[i] < th_l || vals[i] > th_h) vals[i] = 255; //普通こっちでは? //if (vals[i] < th_l) vals[i] = 0; //if (vals[i] > th_h) vals[i] = 255; } color.Item0 = (byte)((vals[1] + vals[2]) / 2.0); indexer[y, x] = color; colors = null; } indexers = null; indexer = null; }
public void 自作反射光除去(Mat[] images, ref Mat DST) { int width = images[0].Width; int height = images[0].Height; MatIndexer<Vec3b>[] indexers = new MatIndexer<Vec3b>[4]; var indexer = new MatOfByte3(DST).GetIndexer(); for (int i = 0; i < 4; i++) indexers[i] = new MatOfByte3(images[i]).GetIndexer(); for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { Vec3b[] colors = new Vec3b[4]; Vec3b color = indexer[y, x]; for (int i = 0; i < 4; i++) colors[i] = indexers[i][y, x]; double[] vals = { 0, 0, 0, 0 }; for (int num = 0; num < 4; num++) vals[num] = colors[num].Item0; Array.Sort(vals);//並び替えを行う.min=vals[0] color.Item0 = (byte)((vals[0] + vals[1] + vals[2]) / 3.0); indexer[y, x] = color; colors = null; } indexers = null; indexer = null; }
/// <summary> /// Draw a contour. /// </summary> /// <param name="img">Image to draw on.</param> /// <param name="color">Color to draw (default, white).</param> public void Render(Mat img, Scalar color) { if (img == null) throw new ArgumentNullException(nameof(img)); if (img.Type() != MatType.CV_8UC3) throw new ArgumentException("Invalid img format (U8 3-channels)"); var indexer = img.GetGenericIndexer<Vec3b>(); int x = StartingPoint.X; int y = StartingPoint.Y; foreach (CvChainCode cc in ChainCode) { indexer[y, x] = new Vec3b((byte) color.Val0, (byte) color.Val1, (byte) color.Val2); x += CvBlobConst.ChainCodeMoves[(int) cc][0]; y += CvBlobConst.ChainCodeMoves[(int) cc][1]; } }
/// <summary> /// /// </summary> /// <param name="labels"></param> /// <param name="blob"></param> /// <param name="imgSrc"></param> /// <param name="imgDst"></param> /// <param name="mode"></param> /// <param name="color"></param> /// <param name="alpha"></param> public static unsafe void PerformOne(LabelData labels, CvBlob blob, Mat imgSrc, Mat imgDst, RenderBlobsMode mode, Scalar color, double alpha) { if (labels == null) throw new ArgumentNullException("labels"); if (blob == null) throw new ArgumentNullException("blob"); if (imgSrc == null) throw new ArgumentNullException("imgSrc"); if (imgDst == null) throw new ArgumentNullException("imgDst"); if (imgDst.Type() != MatType.CV_8UC3) throw new ArgumentException("'img' must be a 3-channel U8 image."); if ((mode & RenderBlobsMode.Color) == RenderBlobsMode.Color) { var pSrc = imgSrc.GetGenericIndexer<Vec3b>(); var pDst = imgDst.GetGenericIndexer<Vec3b>(); for (int r = blob.MinY; r < blob.MaxY; r++) { for (int c = blob.MinX; c < blob.MaxX; c++) { if (labels[r, c] == blob.Label) { byte v0 = (byte) ((1.0 - alpha)*pSrc[r, c].Item0 + alpha*color.Val0); byte v1 = (byte) ((1.0 - alpha)*pSrc[r, c].Item1 + alpha*color.Val1); byte v2 = (byte) ((1.0 - alpha)*pSrc[r, c].Item2 + alpha*color.Val2); pDst[r, c] = new Vec3b(v0, v1, v2); } } } } if (mode != RenderBlobsMode.None) { if ((mode & RenderBlobsMode.BoundingBox) == RenderBlobsMode.BoundingBox) { Cv2.Rectangle( imgDst, new Point(blob.MinX, blob.MinY), new Point(blob.MaxX - 1, blob.MaxY - 1), new Scalar(255, 0, 0)); } if ((mode & RenderBlobsMode.Angle) == RenderBlobsMode.Angle) { double angle = blob.Angle(); double lengthLine = Math.Max(blob.MaxX - blob.MinX, blob.MaxY - blob.MinY) / 2.0; double x1 = blob.Centroid.X - lengthLine * Math.Cos(angle); double y1 = blob.Centroid.Y - lengthLine * Math.Sin(angle); double x2 = blob.Centroid.X + lengthLine * Math.Cos(angle); double y2 = blob.Centroid.Y + lengthLine * Math.Sin(angle); Cv2.Line(imgDst, new Point((int)x1, (int)y1), new Point((int)x2, (int)y2), new Scalar(0, 255, 0)); } if ((mode & RenderBlobsMode.Centroid) == RenderBlobsMode.Centroid) { Cv2.Line(imgDst, new Point((int)blob.Centroid.X - 3, (int)blob.Centroid.Y), new Point((int)blob.Centroid.X + 3, (int)blob.Centroid.Y), new Scalar(255, 0, 0)); Cv2.Line(imgDst, new Point((int)blob.Centroid.X, (int)blob.Centroid.Y - 3), new Point((int)blob.Centroid.X, (int)blob.Centroid.Y + 3), new Scalar(255, 0, 0)); } } }