vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
vb@rchiv Offline-Reader - exklusiv auf der vb@rchiv CD Vol.4  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
Hash 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

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Hash vom Bildern ermitteln und in MS SQL speichern - Datentyp? 
Autor: Jojo
Datum: 30.04.20 20:16

Danke Kuno,

Thema ist damit durch ... ich speicher die Daten als String in der Datenbank und wenn ich die differnenz errechnen muss wandel ich den String wieder in byte() um.

Daaaaaanke für die Hilfe

Joachim

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel