/// <summary> /// Computes an edge image using the provided image. The lower threshold and higher threshold /// provided are those used for hysteresis, on a scale from 0 to 1. /// </summary> /// <param name="image">The image to use for edge-seeking</param> /// <param name="lowThreshold">The lower threshold for hysteresis, from 0 to 1</param> /// <param name="highThreshold">The higher threshold for hysteresis, from 0 to 1</param> /// <returns></returns> public static BinaryImage Compute( GradientImage image, float lowThreshold, float highThreshold ) { IArrayHandler <byte> nms = NonMaximalSuppression(image); return(Hysteresis(image, nms, lowThreshold, highThreshold)); }
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); GradientImage image = (GradientImage)this.Element; CGRect rect = new CGRect(0, 0, image.Width, image.Height); Draw(rect); }
private void CreateViews() { homeImage = new GradientImage { Source = ImageSource.FromResource("Zwaby.Images.child-1245893_1280.jpg", typeof(MainPage).GetTypeInfo().Assembly), Aspect = Aspect.AspectFit, StartColor = Color.FromHex("#008c49"), EndColor = Color.FromHex("#00d2b4") }; zwabyImage = new CircleImage { Source = ImageSource.FromResource("Zwaby.Images.zwabyhomefive.png", typeof(MainPage).GetTypeInfo().Assembly), Aspect = Aspect.AspectFit, BackgroundColor = Color.White, HorizontalOptions = LayoutOptions.Center, Margin = new Thickness(20, 20, 20, 20), CornerRadius = 4.0 }; calendarImage = new CircleImage { Source = "calendaricon.png", Style = Resources["imageIcon"] as Style }; bookingImage = new CircleImage { Source = "bookingicon.png", Style = Resources["imageIcon"] as Style }; profileImage = new CircleImage { Source = "profileicon.png", Style = Resources["imageIcon"] as Style }; bookServiceLabel = new Label { Text = "Book Cleaning", FontFamily = Device.RuntimePlatform == Device.iOS ? "Cabin-Bold" : "Cabin-Bold.ttf#Cabin-Bold" }; bookingDetailsLabel = new Label { Text = "Booking Details", FontFamily = Device.RuntimePlatform == Device.iOS ? "Cabin-Bold" : "Cabin-Bold.ttf#Cabin-Bold" }; profileLabel = new Label { Text = "Profile", FontFamily = Device.RuntimePlatform == Device.iOS ? "Cabin-Bold" : "Cabin-Bold.ttf#Cabin-Bold" }; }
public override void Draw(CGRect rect) { base.Draw(rect); GradientImage image = (GradientImage)this.Element; CGColor startColor = image.StartColor.ToCGColor(); CGColor endColor = image.EndColor.ToCGColor(); var gradientLayer = new CAGradientLayer(); gradientLayer.Frame = rect; gradientLayer.Colors = new CGColor[] { startColor, endColor }; NativeView.Layer.InsertSublayer(gradientLayer, 0); }
protected virtual void OnPopulateMesh(VertexHelper vh) { vh.Clear(); if (this.get_type() == null) { Color32 a = Color32.op_Implicit(((Graphic)this).get_color()); if (Object.op_Inequality((Object)this.get_sprite(), (Object)null)) { Vector2[] vertices = this.get_sprite().get_vertices(); Vector2[] uv = this.get_sprite().get_uv(); vh.AddVert(Vector2.op_Implicit(vertices[0]), GradientImage.MultiplyColor(a, this.BottomLeft), uv[0]); vh.AddVert(Vector2.op_Implicit(vertices[1]), GradientImage.MultiplyColor(a, this.TopLeft), uv[1]); vh.AddVert(Vector2.op_Implicit(vertices[2]), GradientImage.MultiplyColor(a, this.TopRight), uv[2]); vh.AddVert(Vector2.op_Implicit(vertices[3]), GradientImage.MultiplyColor(a, this.BottomRight), uv[3]); } else { Rect rect = ((RectTransform)((Component)this).GetComponent <RectTransform>()).get_rect(); // ISSUE: explicit reference operation vh.AddVert(Vector2.op_Implicit(((Rect)@rect).get_min()), GradientImage.MultiplyColor(a, this.BottomLeft), new Vector2(0.0f, 0.0f)); // ISSUE: explicit reference operation // ISSUE: explicit reference operation vh.AddVert(Vector2.op_Implicit(new Vector2(((Rect)@rect).get_x(), ((Rect)@rect).get_yMax())), GradientImage.MultiplyColor(a, this.TopLeft), new Vector2(0.0f, 1f)); // ISSUE: explicit reference operation vh.AddVert(Vector2.op_Implicit(((Rect)@rect).get_max()), GradientImage.MultiplyColor(a, this.TopRight), new Vector2(1f, 1f)); // ISSUE: explicit reference operation // ISSUE: explicit reference operation vh.AddVert(Vector2.op_Implicit(new Vector2(((Rect)@rect).get_xMax(), ((Rect)@rect).get_y())), GradientImage.MultiplyColor(a, this.BottomRight), new Vector2(1f, 0.0f)); } vh.AddTriangle(0, 1, 2); vh.AddTriangle(2, 3, 0); } else { base.OnPopulateMesh(vh); } }
private static unsafe BinaryImage Hysteresis(GradientImage grad, IArrayHandler <byte> nms, float tlow, float thigh) { int r, c, pos, numedges, highcount; int[] hist = new int[short.MaxValue]; float maximum_mag, lowthreshold, highthreshold; maximum_mag = 0; float[,] magChannel = grad.ExtractChannel(0); short[] mag = new short[magChannel.Length]; fixed(short *dst = mag) { fixed(float *src = magChannel) { float *srcPtr = src; short *dstPtr = dst; for (int i = 0; i < mag.Length; i++, srcPtr++, dstPtr++) { *dstPtr = (short)(*srcPtr * 255); } } } int rows = grad.Rows; int cols = grad.Columns; byte[] edge = new byte[rows * cols]; fixed(byte *src = nms.RawArray) { byte *srcPtr = src; int length = rows * cols; for (pos = 0; pos < length; pos++) { if (*srcPtr++ == POSSIBLE_EDGE) { edge[pos] = POSSIBLE_EDGE; } else { edge[pos] = NOEDGE; } } } for (r = 0, pos = 0; r < rows; r++, pos += cols) { edge[pos] = NOEDGE; edge[pos + cols - 1] = NOEDGE; } pos = (rows - 1) * cols; for (c = 0; c < cols; c++, pos++) { edge[c] = NOEDGE; edge[pos] = NOEDGE; } for (r = 0; r < short.MaxValue; r++) { hist[r] = 0; } for (r = 0, pos = 0; r < rows; r++) { for (c = 0; c < cols; c++, pos++) { if (edge[pos] == POSSIBLE_EDGE) { hist[mag[pos]]++; } } } for (r = 1, numedges = 0; r < short.MaxValue; r++) { if (hist[r] != 0) { maximum_mag = (short)r; } numedges += hist[r]; } highcount = (int)(numedges * thigh + 0.5); r = 1; numedges = hist[1]; while ((r < (maximum_mag - 1)) && (numedges < highcount)) { r++; numedges += hist[r]; } highthreshold = (short)r; lowthreshold = (short)(highthreshold * tlow + 0.5); for (r = 0, pos = 0; r < rows; r++) { for (c = 0; c < cols; c++, pos++) { if ((edge[pos] == POSSIBLE_EDGE) && (mag[pos] >= highthreshold)) { edge[pos] = EDGE; follow_edges(edge, mag, pos, lowthreshold, cols); } } } for (r = 0, pos = 0; r < rows; r++) { for (c = 0; c < cols; c++, pos++) { if (edge[pos] != EDGE) { edge[pos] = NOEDGE; } } } BinaryImage edgeImage = new BinaryImage(rows, cols); fixed(bool *dst = edgeImage.RawArray) { bool *dstPtr = dst; int length = rows * cols; for (pos = 0; pos < length; pos++) { *dstPtr++ = edge[pos] == EDGE; } } return(edgeImage); }
Compute(GradientImage image) { return(Compute(image, LOWER_THRESHOLD, HIGHER_THRESHOLD)); }
private static unsafe IArrayHandler <byte> NonMaximalSuppression(GradientImage magImage) { int nrows = magImage.Rows; int ncols = magImage.Columns; int rowcount, colcount, count; float[,] magVals = magImage.ExtractChannel(0); float[,] gradxVals = magImage.ExtractChannel(2); float[,] gradyVals = magImage.ExtractChannel(3); byte[] data = new byte[nrows * ncols]; fixed(byte *result = data) { fixed(float *mag = magVals, gradx = gradxVals, grady = gradyVals) { float *magrowptr, magptr; float *gxrowptr, gxptr; float *gyrowptr, gyptr; float z1, z2; float m00, gx, gy; float mag1, mag2, xperp, yperp; byte * resultrowptr, resultptr; /**************************************************************************** * Zero the edges of the result image. ****************************************************************************/ for (count = 0, resultrowptr = result, resultptr = result + ncols * (nrows - 1); count < ncols; resultptr++, resultrowptr++, count++) { *resultrowptr = *resultptr = 0; } for (count = 0, resultptr = result, resultrowptr = result + ncols - 1; count < nrows; count++, resultptr += ncols, resultrowptr += ncols) { *resultptr = *resultrowptr = 0; } /**************************************************************************** * Suppress non-maximum points. ****************************************************************************/ for (rowcount = 1, magrowptr = mag + ncols + 1, gxrowptr = gradx + ncols + 1, gyrowptr = grady + ncols + 1, resultrowptr = result + ncols + 1; rowcount < nrows - 2; rowcount++, magrowptr += ncols, gyrowptr += ncols, gxrowptr += ncols, resultrowptr += ncols) { for (colcount = 1, magptr = magrowptr, gxptr = gxrowptr, gyptr = gyrowptr, resultptr = resultrowptr; colcount < ncols - 2; colcount++, magptr++, gxptr++, gyptr++, resultptr++) { m00 = *magptr; gx = *gxptr; gy = *gyptr; if (m00 == 0) { *resultptr = NOEDGE; continue; } else { xperp = -(gx = *gxptr) / ((float)m00); yperp = (gy = *gyptr) / ((float)m00); } if (gx >= 0) { if (gy >= 0) { if (gx >= gy) { /* 111 */ /* Left point */ z1 = *(magptr - 1); z2 = *(magptr - ncols - 1); mag1 = (m00 - z1) * xperp + (z2 - z1) * yperp; /* Right point */ z1 = *(magptr + 1); z2 = *(magptr + ncols + 1); mag2 = (m00 - z1) * xperp + (z2 - z1) * yperp; } else { /* 110 */ /* Left point */ z1 = *(magptr - ncols); z2 = *(magptr - ncols - 1); mag1 = (z1 - z2) * xperp + (z1 - m00) * yperp; /* Right point */ z1 = *(magptr + ncols); z2 = *(magptr + ncols + 1); mag2 = (z1 - z2) * xperp + (z1 - m00) * yperp; } } else { if (gx >= -gy) { /* 101 */ /* Left point */ z1 = *(magptr - 1); z2 = *(magptr + ncols - 1); mag1 = (m00 - z1) * xperp + (z1 - z2) * yperp; /* Right point */ z1 = *(magptr + 1); z2 = *(magptr - ncols + 1); mag2 = (m00 - z1) * xperp + (z1 - z2) * yperp; } else { /* 100 */ /* Left point */ z1 = *(magptr + ncols); z2 = *(magptr + ncols - 1); mag1 = (z1 - z2) * xperp + (m00 - z1) * yperp; /* Right point */ z1 = *(magptr - ncols); z2 = *(magptr - ncols + 1); mag2 = (z1 - z2) * xperp + (m00 - z1) * yperp; } } } else { if ((gy = *gyptr) >= 0) { if (-gx >= gy) { /* 011 */ /* Left point */ z1 = *(magptr + 1); z2 = *(magptr - ncols + 1); mag1 = (z1 - m00) * xperp + (z2 - z1) * yperp; /* Right point */ z1 = *(magptr - 1); z2 = *(magptr + ncols - 1); mag2 = (z1 - m00) * xperp + (z2 - z1) * yperp; } else { /* 010 */ /* Left point */ z1 = *(magptr - ncols); z2 = *(magptr - ncols + 1); mag1 = (z2 - z1) * xperp + (z1 - m00) * yperp; /* Right point */ z1 = *(magptr + ncols); z2 = *(magptr + ncols - 1); mag2 = (z2 - z1) * xperp + (z1 - m00) * yperp; } } else { if (-gx > -gy) { /* 001 */ /* Left point */ z1 = *(magptr + 1); z2 = *(magptr + ncols + 1); mag1 = (z1 - m00) * xperp + (z1 - z2) * yperp; /* Right point */ z1 = *(magptr - 1); z2 = *(magptr - ncols - 1); mag2 = (z1 - m00) * xperp + (z1 - z2) * yperp; } else { /* 000 */ /* Left point */ z1 = *(magptr + ncols); z2 = *(magptr + ncols + 1); mag1 = (z2 - z1) * xperp + (m00 - z1) * yperp; /* Right point */ z1 = *(magptr - ncols); z2 = *(magptr - ncols - 1); mag2 = (z2 - z1) * xperp + (m00 - z1) * yperp; } } } /* Now determine if the current point is a maximum point */ if ((mag1 > 0.0) || (mag2 > 0.0)) { *resultptr = NOEDGE; } else { if (mag2 == 0.0) { *resultptr = NOEDGE; } else { *resultptr = POSSIBLE_EDGE; } } } } } } ByteArrayHandler handler = new ByteArrayHandler(nrows, ncols, 1); fixed(byte *dst = handler.RawArray) { byte *dstPtr = dst; int length = nrows * ncols; for (int pos = 0; pos < length; pos++) { *dstPtr++ = data[pos]; } } //MonochromeImage mono = new MonochromeImage(nrows, ncols); //for (int r = 0; r < nrows; r++) // for (int c = 0; c < ncols; c++) // mono[r, c] = handler[r, c, 0]; //mono.ToRGB().Save("cannyNMS.bmp"); return(handler); }