Hallo zusammen,
ich habe mir folgendes Ziel in den Kopf gesetzt:
Ich möchte in einem Bild, welches in der Art wie das unten zu sehende Original aussieht, aber bei dem die Freiformen unterschiedlich angeordnet sein können und auch die Anzahl unterschiedlich sein kann, lineare Funktionen detektieren.
Bisher habe ich mittels einer Sobel Faltung das Bild (siehe Code) in ein Bytearray überführt um die Kanten zu finden, siehe Bild Sobel.
Spoiler anzeigen
Das Zielbild sollte in etwa so aussehen wie in rot dargestellt, aber so dass mir die linearen Funktion vorliegen. Die linearen Funktionen befinden sich ungefähr im der Mittelachse der Freiformen. Ungefähr deshalb, weil die Berandungen der Freiformen nicht unbedingt parallel und gerade sind, das heißt ich müsste sowieso über irgendeine Art von Ausgleichsgerade nachdenken
Mir fehlt jetzt allerdings jetzt die zündende Idee, wie ich aus dem Bytearray, im Code
Hat jemand Googlevorschläge oder einen ganz anderen Lösungsansatz für mich?
Überlegt habe ich mir auch, dass ich auf das Original Rechtecke so gut es geht, Rechtecke matche, und dann über den Mittelpunkt der kurzen Achse meine zwei Punkte für die Funktion habe, aber auch hier ist das nur eine Idee ohne konkreten Ansatz für einen Algorithmus.
Viele Grüße
ich habe mir folgendes Ziel in den Kopf gesetzt:
Ich möchte in einem Bild, welches in der Art wie das unten zu sehende Original aussieht, aber bei dem die Freiformen unterschiedlich angeordnet sein können und auch die Anzahl unterschiedlich sein kann, lineare Funktionen detektieren.
Bisher habe ich mittels einer Sobel Faltung das Bild (siehe Code) in ein Bytearray überführt um die Kanten zu finden, siehe Bild Sobel.
VB.NET-Quellcode
- Public Class Image
- Private _image As New Image()
- Public ReadOnly Property Image As ImageSource
- Get
- Return _image.Source
- End Get
- End Property
- Public Sub New(img As BitmapImage)
- Dim grayBmp = ConvertToGrayscale(img)
- Dim threshold As Integer = 400
- Dim stride = CInt(grayBmp.PixelWidth * grayBmp.Format.BitsPerPixel / 2)
- stride += (stride Mod 4) * 4
- Dim pixelLength As Integer = CInt(stride * grayBmp.PixelHeight * grayBmp.Format.BitsPerPixel / 2 - 1)
- Dim picture As Byte() = New Byte(pixelLength) {}
- Dim filterPicture As Byte() = New Byte(pixelLength) {}
- grayBmp.CopyPixels(picture, stride, 0)
- Dim height As Integer = grayBmp.PixelHeight - 1
- Dim width As Integer = Convert.ToInt32((grayBmp.Width - 1) * grayBmp.Format.BitsPerPixel)
- filterPicture = SobelConvolution(picture, pixelLength, height, width, stride, threshold)
- _image.Source = BitmapSource.Create(grayBmp.PixelWidth, grayBmp.PixelHeight, grayBmp.DpiX, grayBmp.DpiY, PixelFormats.Gray8, Nothing, filterPicture, stride)
- End Sub
- Private Function ConvertToGrayscale(original As BitmapImage) As FormatConvertedBitmap
- Dim grayBitmap As FormatConvertedBitmap = New FormatConvertedBitmap()
- grayBitmap.BeginInit()
- grayBitmap.Source = original
- grayBitmap.DestinationFormat = PixelFormats.Gray8
- grayBitmap.EndInit()
- Return grayBitmap
- End Function
- Private Function SobelConvolution(pictureArray As Byte(), length As Integer, height As Integer, width As Integer, stride As Integer, threshold As Integer) As Byte()
- Dim byteArray As Byte() = New Byte(length) {}
- Dim sx, sy, s As Double
- ' Sobel-Feldmann convolution operators:
- ' sobel_x = [1,0,-1] sobel_y =[ 1, 2, 1]
- ' [2,0,-2] [ 0, 0, 0]
- ' [1,0,-1] [-1,-2,-1]
- For x = 1 To height - 1
- For y = 1 To width - 1
- sx = 1 * GetPixelFromArray(y - 1, x, pictureArray, stride) +
- 2 * GetPixelFromArray(y, x + 1, pictureArray, stride) +
- 1 * GetPixelFromArray(y + 1, x + 1, pictureArray, stride) +
- -1 * GetPixelFromArray(y - 1, x - 1, pictureArray, stride) +
- -2 * GetPixelFromArray(y, x - 1, pictureArray, stride) +
- -1 * GetPixelFromArray(y + 1, x - 1, pictureArray, stride)
- sy = +1 * GetPixelFromArray(y + 1, x + 1, pictureArray, stride) +
- -1 * GetPixelFromArray(y - 1, x + 1, pictureArray, stride) +
- +2 * GetPixelFromArray(y + 1, x, pictureArray, stride) +
- -2 * GetPixelFromArray(y - 1, x, pictureArray, stride) +
- +1 * GetPixelFromArray(y + 1, x - 1, pictureArray, stride) +
- -1 * GetPixelFromArray(y - 1, x - 1, pictureArray, stride)
- s = Math.Abs(sy) + Math.Abs(sx)
- If s <= threshold Then
- s = 255
- Else
- s = 0
- End If
- byteArray(y + x * stride) = CByte(s)
- Next
- Next
- Return byteArray
- End Function
- Private Function GetPixelFromArray(x As Integer, y As Integer, pictureArray As Byte(), stride As Integer) As Byte
- Dim byteToGet As Byte = pictureArray(y * stride + x)
- Return byteToGet
- End Function
- End Class
Das Zielbild sollte in etwa so aussehen wie in rot dargestellt, aber so dass mir die linearen Funktion vorliegen. Die linearen Funktionen befinden sich ungefähr im der Mittelachse der Freiformen. Ungefähr deshalb, weil die Berandungen der Freiformen nicht unbedingt parallel und gerade sind, das heißt ich müsste sowieso über irgendeine Art von Ausgleichsgerade nachdenken
Mir fehlt jetzt allerdings jetzt die zündende Idee, wie ich aus dem Bytearray, im Code
pictureArray
genannt irgendetwas in der Art rauslesen kann, geschweige denn mir dir Funktionsvorschrift bekomme.Hat jemand Googlevorschläge oder einen ganz anderen Lösungsansatz für mich?
Überlegt habe ich mir auch, dass ich auf das Original Rechtecke so gut es geht, Rechtecke matche, und dann über den Mittelpunkt der kurzen Achse meine zwei Punkte für die Funktion habe, aber auch hier ist das nur eine Idee ohne konkreten Ansatz für einen Algorithmus.
Viele Grüße