Grow R503 Fingerprintsensor Imagedaten auslesen

OP #7607869
Lesenswert?

Hat das hier schon mal jemand hinbekommen? Also das Auslesen selber ist dokumentiert, man schickt ein Kommando zum Fingerabdruck speichern (intern), dann eines zum Upload und dann bekomme ich 18270 Byte Daten. Die Doku ist etwas dünn, in der neuesten die ich gefunden habe (in der Dropbox von Grow) steht das ein Byte 2x 4 Bit Pixel enthält, das eine für die aktuelle Zeile und das andere für die nächste Zeile. Die Daten packe ich in ein Bitmapfile, ich sehe aber nur Pixelsalat, bzw. in etwa schon einen Fingerprint, aber mit Versatz. Auch in der Demo App des Herstellers wird das für diesen Sensor nicht richtig angezeigt. Enroll/Search funktioniert, nur eben das Image anzeigen nicht richtig. Das Bild ist im Anhang, die Kreise habe ich reingemalt um meinen Stinkefinger nicht zu zeigen. Da scheint auch noch was mit der Farbpalette faul zu sein. Ich erweitere die 4 Bit Pixel auf 8 Bit und habe eine LUT mit 256 Einträgen. In einem Vergleichsbild von der Demo SW sehen Header und LUT gleich aus, da passt das Graubild aber.

Und noch ein paar Infos die der Sensor verrät:

1
Status  : 0x0
2
Sys ID  : 0x0
3
Capacity: 200
4
Security level: 3
5
Device address: -1
6
Packet len: 128
7
Baud rate: 57600
8

9
Module Type: R5xx
10
Hardware Version: 01.01
11
Module Batch Number: 1111
12
Module Serial Number: 20060402
13
Database size: 200
14
Template size: 1536
15
Sensor Type: GR192RGB
16
Sensor width/height : 192 192
17
starting network
18
network is up, IP:  192.168.100.134
19
Server is listening at http://192.168.100.134:8080
20
TFTPServer starting...
21
genImage result: 0x0
22
  image size: 18720
23
uploadImage result: 0x0
24
 block count: 144
Angehängte Dateien:
OP #7607929
Lesenswert?

Es gibt eine Anleitung in der schon einiges drinsteht, zum Format eben nur 2x 4 Bit, nichts von Komprimierung. Ich speichere das konvertierte Array in eine Bitmap Datei auf SD Karte, kann diese über eine Webseite anzeigen oder per TFTP abholen. Der Sensor liefert immer die 18270 Byte auf eine Anfrage zum Upload.

Doku ist China typisch in Dropbox: https://www.dropbox.com/sh/epucei8lmoz7xpp/AAAmon04b1DiSOeh1q4nAhzAa?e=1&spm=a2g0o.detail.1000023.1.676claGNlaGNb1&dl=0

https://www.dropbox.com/sh/pznvlzx8qx5nfr3/AABpzhSyjqH0qWNYgMvxqAA9a?e=1&spm=a2g0s.imconversation.0.0.109b3e5fckU9p0&dl=0

Auch in den Sourcecodes von Grow konnte ich nicht finden, der relevante Interface Teil ist in einer DLL ohne Quellcode.

1
When uploading or downloading images through the UART port, only the high four bits of pixel
2
bytes are used to speed up the transmission, that is, use gray level 16, two pixels are combined into one
3
byte. (The high four bits are a pixel, the low four bits are a pixel in the next adjacent column of the same
4
row, that is, two pixels are combined into one byte and transmitted)
5
Since the image has 16 gray levels, when it is uploaded to PC for display (corresponding to BMP
6
format), the gray level should be extended (256 gray levels, that is, 8bit bitmap format)
#7607946
Lesenswert?

J. S. schrieb:

Die Doku ist etwas dünn, in der neuesten die ich gefunden habe (in der Dropbox von Grow) steht das ein Byte 2x 4 Bit Pixel enthält, das eine für die aktuelle Zeile und das andere für die nächste Zeile.

J. S. schrieb:

two pixels are combined into one byte. (The high four bits are a pixel, the low four bits are a pixel in the next adjacent column of the same row

Beim Lesen ist mir aufgefallen, dass Du im Eröffnungsposting geschrieben hast, in einem Byte wären zwei Pixel benachbarter Zeilen, die englische Dokumentation im zweiten Posting hingegen von zwei Pixeln benachbarter Spalten spricht.

Hast Du beim Lesen der Doku eventuell einfach versehentlich "column" mit "Zeile" statt mit "Spalte" übersetzt und das aufgrund dieses kleinen Irrtums dann falsch implementiert?

OP #7607967
Lesenswert?

Ich hatte im Code zuerst zwei Nachbarpixel in einer Zeile gemacht weil dieser Hinweis in der Doku erst in neueren Revisionen hinzugekommen ist. Danach habe ich es geändert, dafür ist der twoLineBuffer im Code. Sieht aber immer noch nicht passend aus. Auch die RGB LED ist erst in der neuen Doku drin.

#7608046
Lesenswert?

J. S. schrieb:

Ich hatte im Code zuerst zwei Nachbarpixel in einer Zeile gemacht weil dieser Hinweis in der Doku erst in neueren Revisionen hinzugekommen ist. Danach habe ich es geändert, dafür ist der twoLineBuffer im Code.

Das habe ich ehrlich gesagt nicht 100%ig verstanden, aber egal.

Ich habe jetzt auch mal den Code überflogen und meiner Interpretation nach behandelt Dein Code die Daten in der Tat so, als würde ein Byte der Rohdaten die Pixel zweier aufeinanderfolgender Zeilen in der selben Spalte enthalten (daher ja auch die Verwendung eines "twoLineBuffer"). Laut dem besagten Hinweis in der Doku sind es aber (wie üblich) die Pixel zweier aufeinanderfolgenden Spalten in der selben Zeile.

Wenn Du das vorher genau anders herum implementiert hattest, das Bild aber trotzdem fehlerhaft war, dann steckt eventuell zusätzlich noch ein anderer kleiner Fehler im Code - aber meiner Meinung nach hat der Code zumindest an dieser Stelle aktuell einen Fehler.

OP #7608089
Lesenswert?

Joachim S. schrieb:

aber meiner Meinung nach hat der Code zumindest an dieser Stelle aktuell einen Fehler.

Danke fürs aufpassen, du hattest Recht, war zu spät gestern und da ist das so eine Sache mit den Zeilen und Spalten. War eine lange Geburt, aber jetzt passt es.

Da war aber noch ein grober Schnitzer drin. Ich habe die Adafruit Lib als Basis genommen und das fehlende Kommando zum Auslesen eingebaut. Da wird die gelesene Paketlänge aber blöderweise als Bruttowert eingetragen, mit der Länge der CRC (die in der Lib auch nicht ausgewertet wird). Nach Korrektur um -2 pro Packet auf Nettolänge passt die Gesamtlänge jetzt auch, es kommmen 18432 Byte, entspricht 192 * 192/2,

1
  // image data 4 Bit -> 8 Bit
2
  for(int y=0; y < 192; y++) {
3
    for(int x=0; x < 192/2; x++) {
4
      uint8_t val1 = (imageBuffer[x + y*96] >> 4) * 16;
5
      uint8_t val2 = (imageBuffer[x + y*96] & 0xf) * 16;
6
      lineBuffer[2*x] = val1;
7
      lineBuffer[2*x + 1] = val2;
8
    }
9
    imageFile.write(lineBuffer, sizeof(lineBuffer));
10
  }

Bleibt noch eine Unschärfe mit der Farbpalette, aber das finde ich auch noch.

hier ist noch der Teil zum Image lesen, da ist noch Debugzeug drin das raus muss. Und die Prüfung der Länge des ImageBuffer fehlt noch. Eventuell mache ich noch einen PR dazu.

1
DigitalOut  testPin1(PA_6);
2
DigitalOut  testPin2(PA_4);
3

4
uint8_t Adafruit_Fingerprint::uploadImage(uint8_t *imageBuffer) {
5
    GET_CMD_PACKET(FINGERPRINT_UP_IMG);
6

7
    uint8_t result = packet.data[0];
8
    if (result == FINGERPRINT_OK) {
9
      int length = 0;
10
      packetCount = 0;
11
      
12
      testPin2 = 1;
13
      
14
      packet.type = 0x02;
15
      while (packet.type == 0x02) {
16
          testPin1 = 1;
17

18
          result = getStructuredPacket(&packet);
19
          if (result != FINGERPRINT_OK) 
20
            break;
21
          if (imageBuffer)
22
            memcpy(&imageBuffer[length], packet.data, packet.length-2);
23
          length += packet.length-2;
24
          packetCount++;
25
          
26
          testPin1 = 0;
27
      }
28
      testPin2 = 0;
29

30
      printf("  image size: %d\n", length);
31
    }
32

33
    return result;
34
}
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren