| |
VB.NET - FortgeschritteneHash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: Jojo | Datum: 29.04.20 20:56 |
| Hallo,
ich kämpfe seit länderem mit dem Thema wie ich Bilder vergleichen und wieder erkennen kann.
Nach Problemen mit meiner bisherigen Funktion möchte ich Phash verwenden (nuget: Shipwreck.Phash)
Das funktioniert soweit auch ...
Imports Shipwreck.Phash
Imports Shipwreck.Phash.Bitmaps
...
Using ms As New IO.MemoryStream(IO.File.ReadAllBytes("c:\temp\temp.jpg"))
Using originalBild As Image = Image.FromStream(ms)
Dim bitmap = CType(originalBild, Bitmap)
Dim shash As Shipwreck.Phash.Digest = ImagePhash.ComputeDigest( _
bitmap.ToLuminanceImage())
End Using
End Using Das Shash ist ein Objekt vom type Shipwreck.Phash.Digest ... Wenn ich das als String ausgeben lasse sieht das z.B. so aus:
0x7879FF750079E975097DE2701380DA6C1887D36A2380C7712B83C16A3385B76B3D84AE6B4883A26D
Ich möchte zu mehreren Milionen Bildnamen den Hash Key in der Datenbank speichern (MS SQL Server) um doppelte schnell in der DB erkennen zu können.
Mein Problem ist, dass ich diese Digest Object in nichts umgewandelt bekomme außer in einen String
Frage: Wer hat eine Idee wie ich das umwandeln und platzsparend in der DB speichern kann. Mein bisheriger Schlüssel ist ein INT64 Datentyp den ich im SQL Server in BigInt speicher ...
Danke für Denkanregungen
Joachim | |
Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: Wobi | Datum: 30.04.20 02:27 |
| Hallo,
mit konkretem Code kann ich dir leider nicht helfen,
aber gestatte mir ein paar Anmerkungen bzw. Fragen.
Zitat: | |
Ich möchte zu mehreren Milionen Bildnamen den Hash Key in der
Datenbank speichern (MS SQL Server) um doppelte schnell in
der DB erkennen zu können.
| |
Was für einen Vorteil versprichst du dir davon viele Daten in die DB zu schaufeln und erst dann zu prüfen, ob es sich um doppelte Daten handelt. Je größer die Datenmenge ist, desto unwirtschaftlicher ist es.
Wenn die Gefahr von doppelten Daten die aussortiert, verhindert werden müssen usw. gehe ich immer so vor, dass die neuen Daten gegenüber dem vorhandenen Datenbestand geprüft werden und dann entsprechend entschieden wird.
Also 1 Mio Daten und ein Datensatz kommt dazu ist schneller und besser geprüft, als 1 Mio Daten gegen 1 Mio Daten zu prüfen.
Zitat: | |
Frage: Wer hat eine Idee wie ich das umwandeln und
platzsparend in der DB speichern kann.
| |
Platzsparend ist ja immer Daten zu vermeiden, je weniger Daten drin sind die nicht rein gehören desto weniger Arbeit hast du nachher. Und für den User ist es auch komfortabler wenn seine neu einzutragenden Daten direkt geprüft werden anstatt erst mal aufgenommen zu werden und später bekommt er das Ergebnis.
Ok, je höher die zu prüfende Datenmenge ist, desto länger dauert es, das ist keine Frage. Aber man sollte versuchen die Datenmenge die zu prüfen ist möglichst zu reduzieren soweit es geht.
Datenvermeidung ist die sparsamste Möglichkeit Daten zu sparen.
Gruß
Frank | |
Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: Jojo | Datum: 30.04.20 08:06 |
| Hallo Frank,
ja, eine Antwort ist es nicht. Ich wollte das auch nicht so genau erklären. Die Bilder liegen nicht in der Datenbank sondern im Internet auf unterschiedlichen Servern. Ich speicher die Url und lade dann einmal das Bild um Verschau und Hash zu erstellen. In der DB ist dan nur die URL, die Verknüpfung und der HASH.
Joachim
Joachim | |
Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: effeff | Datum: 30.04.20 09:47 |
| Diese Funktion reicht Dir für das Erstellen eines Hashwertes nicht aus?
https://dotnet-snippets.de/snippet/den-md5-hash-einer-datei-ermitteln/77
@Wobi: //Was für einen Vorteil versprichst du dir davon viele Daten in die DB zu schaufeln und erst dann zu prüfen, ob es sich um doppelte Daten handelt. Je größer die Datenmenge ist, desto unwirtschaftlicher ist es.//
Das braucht er doch gar nicht; Er kann doch bereits beim Eintragen in die DB prüfen, ob der Hashwert schon vorhanden ist - oder quick`n`dirty die entsprechende Column auf Unique setzen...
EALA FREYA FRESENA | |
Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: Jojo | Datum: 30.04.20 10:44 |
| Der MD5 Hash war so eine meiner ersten Versuche. Das habe ich vor viele Jahren aufgegeben. Damit findest Du nur exakt gleiche Bilder.
Wenn Größe verändert wurde oder die Qualität der Bilder geht das alles nicht mehr.
Meine Funktion läd das Bild, schneidet den Hintergrund, glättet Kompessionsfehler usw.
Erst dan wird das Bild verglichen.
Wen es interessiert, der findet hier einen gut lesbaren Artikel dazu:
https://content-blockchain.org/research/testing-different-image-hash-functions/
Einen zusätzlichen Hash über den PHash kann ich nicht bilden, weil ich sonst nicht die Abweichung bestimmen kann
var score = ImagePhash.GetCrossCorrelation(hash1, hash2); Ich bin eigentlich soweit mit der Funktion zufrieden. Mein Problem ist aktuell das Speichern der pHash in der MSSQL datenbank
Einige Leute empfehlen das als Varbinary und andere als VarChar zu speichern.
Mir ist aber nicht klar, wie ich aus den String wieder ein Byte mache .... Byte() -> speichern DB char -> lesen String -> vergleichen Byte()
Dim bitmap = CType(MyCropImage, Bitmap)
Dim shash As Shipwreck.Phash.Digest = ImagePhash.ComputeDigest( _
bitmap.ToLuminanceImage())
Dim i As Byte() = shash.Coefficients
'I.tostring =
' 0x7879FF750079E975097DE2701380DA6C1887D36A2380C7712B83C16A3385B76B3D84AE6B488
' 3A26D
'lese ich den Wert aus der DB ... ist es ein String
HashFromDB = _
"0x7879FF750079E975097DE2701380DA6C1887D36A2380C7712B83C16A3385B76B3D84AE6B4" & _
"83A26D" wie bekomme ich den wieder in ein Byte() um den zu vergleichen?
Joachim | |
Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: Kuno60 | Datum: 30.04.20 12:34 |
| Hallo Joachim,
der von dir angegebene Hex-String stellt einen 40 Byte Wert dar, das entspricht 320 Bits.
Dezimal wäre das:
1005220148186726791914816740947805471722513971014241448469666502656196122123382739331844329939565
So große Zahlen kann man effektiv nur als Byte-Array in der Datenbank speichern.
Zwei Byte-Arrays kann man mit SequenceEqual vergleichen.
Wenn du bei:
Dim i As Byte() = shash.Coefficients
bereits ein Byte-Array hast, warum speicherst du es dann als String in der DB?
und i.ToString gibt normalerweise den Wert nicht als Hex-String zurück, dazu muss eine entsprechende Erweiterung vorhanden sein.
Zwei Hex-Strings kann man direkt miteinander vergleichen ohne sie erst in ein Byte-Array umwandeln zu müssen. Diese brauchen aber mehr Platz in der DB. | |
Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: Jojo | Datum: 30.04.20 13:40 |
| Hallo Kuno,
ja, das ist genau mein Punkt.
Im Programm habe ich die Werte als Byte() vorliegen.
Wenn ich die wieder im Programm vergleichen will brauche ich die wieder als Byte()
Zum speichern in MSSQL Server brauche ich eine schnelle Lösung. Auf dem Feld muss ich einen Index aufbauen können und auch mit Joins arbeiten können
select * from TabelleA where Phash='hashkey'
select * from A inner Join B on A.Phash=bB.Phash Dazu kommt, dass ich die Datenbank über Datatable/Datarow lese. Damit muss der Datentyp in dem ich das in der Datenbank speicher ein Datentyp sein, der auch im Datarow dann als ein Byte() übernommen wird. Welchen Datentyp würdest Du wählen?
Alternativ wäre ein VarChar Datentype:
insert into A (EAN,Phash) values ('12345..','0x7879FF750079E97509...') Der ist zwar einfach zu lesen/Schreiben/verknüpfen, aber braucht halt mehr Speicherplatz und wie bekommen ich den wird in ein Byte() umgewandelt ... Daran hänge ich aktuell
Kanst Du mir sagen wie ich aus einen String
"0x7879FF750079E975097DE2701380DA6C1887D36A2380C7712B83C16A3385B76B3D84AE6B4883A26D" wieder ein Byte() Objekt mache?
Joachim
Joachim | |
Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: Kuno60 | Datum: 30.04.20 14:43 |
| Hallo Joachim,
Datenbanken sind nicht so mein Thema, aber wie du den Hex-String in ein Byte() umwandeln kannst, kann ich dir zeigen.
'Der Hex-String ohne 0x am Anfang!
Dim x As String = _
"7879FF750079E975097DE2701380DA6C1887D36A2380C7712B83C16A3385B76B3D84AE6" & _
"4883A26D"
'Einlesen in BigInteger
Dim i As BigInteger = BigInteger.Parse(x, _
Globalization.NumberStyles.HexNumber)
'Das Byte-Array
Dim ba As Byte() = i.ToByteArray Benötigt den Verweis auf System.Numerics | |
Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: Jojo | Datum: 30.04.20 17:56 |
| Hey Kuno,
es funktioniert nicht ...
'Der Hex-String ohne 0x am Anfang!
Dim x As String = _
"5B74BEFF5AD2346A8D1B4B00623E23444E5F47568141745A647259994A697F425B454749474" & _
"396B"
'Einlesen in BigInteger
Dim b As System.Numerics.BigInteger = System.Numerics.BigInteger.Parse(x, _
Globalization.NumberStyles.HexNumber)
'b=7630816972431674181833850499599310621001778199538576802763606114743399308556
' 54039093644937214315
'Das Byte-Array
Dim ba As Byte() = b.ToByteArray So wie ich das sehe, ist das Byte Array vertauscht worden in der Reihenfolge ...
0 wird 39, 1 wird 38 usw.
sonst sieht das alles top aus ...
Joachim | |
Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? | | | Autor: Kuno60 | Datum: 30.04.20 19:39 |
| Jojo schrieb:
Zitat: | | So wie ich das sehe, ist das Byte Array vertauscht worden in der Reihenfolge ...
0 wird 39, 1 wird 38 usw. | |
Das Byte-Array hat die normale Reihenfolge, also das niederwertigste Byte hat den Index 0.
Wenn du es umgekehrt brauchst, so kannst du mit Reverse die Reihenfolge umkehren.
Dim ba As Byte() = b.ToByteArray.Reverse.ToArray | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
Neu! sevDTA 3.0 Pro
SEPA mit Kontonummernprüfung
Erstellen von SEPA-Dateien mit integriertem BIC-Verzeichnis und Konto- nummern-Prüfverfahren, so dass ungültige Bankdaten bereits im Vorfeld ermittelt werden können. Weitere InfosTipp des Monats TOP Entwickler-Paket
TOP-Preis!!
Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR...
Jetzt nur 599,00 EURWeitere Infos
|