# Barcode question Type #2

Closed
opened this issue Nov 23, 2012 · 34 comments
Labels
Milestone

### benzea commented Nov 23, 2012

 This was an idea I had a while ago. One could add a barcode question type, which is simply a blank field that will be passed to zbar for analysis. Usage Scenario: Add field to identify the person that is filling out the questionnaire Hand out the same questionnaire to everyone Hand out Barcode Stickers separately to identify specific persons.

### ferdisdot commented Apr 8, 2013

 Barcode fields may also be interesting to avoid some privacy issues. One can use similar looking barcodes for each posibility. This makes it possible to provide answers in a not human readable way. This may be interesting for e.g. medicinical surveys.
pushed a commit that referenced this issue Oct 16, 2014
 Merge pull request #2 from 3dna/people/qr-python 
 29306a5 
People/qr python

### thomasfedb commented May 21, 2017

 Would be very helpful for my purposes. We often attached patient stickers to forms, which include a barcode or QR code.

### benzea commented May 24, 2017

 It is rather simple to implement. Basically just requires: Subclass text fields Create buddies (basically implement subclassed behaviour; override recognize to fill in text from barcode) Making it usable from LaTeX in a nice way (this might be the ugliest part) Adding the hook to the parser (trivial)
added this to the 2.0 milestone Jan 19, 2019
added a commit that referenced this issue Jan 26, 2019
 Add QR code recognised Codebox 
 9f01fe4 
This is similar to a textbox but designed to hold a QR code which is
reported as a string.

Addresses #2 in the main program.

### benzea commented Feb 17, 2019

 So, now the question is, how to make this reasonable usable on the LaTeX side. As I see it, it would be similar to a textbox in most cases. So: We generally need to generate a question per box; in the class, I could imagine generating a header and one or more textbox questions with codebox type boxes. The box size doesn't make sense to be huge, i.e. a few cm wide is good enough. We probably want some sort of (default) placeholder inside the box, any ideas? Maybe some generic QR code icon? As a start, we could just add the low level support to generate these boxes, add an example, and then see how people want to use the feature.

### jdanion commented Feb 19, 2019

 Would it be explicit enough with something like this ? But the problem is, I have no idea how to do it in latex. I did some research with /tcolorbox, tikz https://tex.stackexchange.com/questions/251670/dotted-frame-around-the-text But no solution for the moment

### benzea commented Feb 20, 2019

 We could do that too. I was thinking of leaving the black frame as is, but putting a "qr code" icon into it (which wouldn't be a valid qr code obviously). Doing so should be relatively simple already with the things that sdapsbase provides.

### benzea commented Feb 20, 2019

 Dotted frame would actually also be easy. The frame is drawn using tikz/pgf, so there is a lot of things you can do.
added a commit to sdaps/sdaps-class that referenced this issue Mar 31, 2019
 WIP: Codebox (QR code/barcode) support for text fields 
 d06e78b 
See issue sdaps/sdaps#2
closed this in  6303c19  Mar 31, 2019

### benzea commented Mar 31, 2019

 Alright, I merged some experimental support. I haven't actually tested this properly to be honest, so please shout at the slightest issue!

### benzea commented Mar 31, 2019 • edited

 Also, I would like to add some nice wrappers to make it more usable. I really need some feedback on how people use it to do so.

### jdanion commented Mar 31, 2019 • edited

 Hi, great stuff, i managed to test it with my tex editor but can't setup it with sdaps correctly, It fails with : "Error: Caught an Exception while parsing the SDAPS file. The current state is: Questionnaire 1(Text) text {1} 0(Codebox ) 12.0 21.6 58.4 42.1" I couln't find any clue in questionnaire.log edit : it seems it may due to columns frame as it works when there is only one codebox alone in a tex edit 2 : it works when the codebox is not the first item

### benzea commented Apr 1, 2019

 Ah, yes. The reason is that the section numbering clashes with the question numbering. It will work fine if you simply put the question underneath the first section header. Or, you can use \sdaps_classic_ensure_section: which will insert an invisible section with number 0.

### jdanion commented Apr 1, 2019 • edited

 Ok thanks. I went further and still some trouble. When doing sdaps recognize, i got : File "/usr/local/lib/python3.7/site-packages/sdaps/recognize/buddies.py", line 915, in recognize res = read_barcode(surface, matrix.mm_to_px(), NameError: name 'read_barcode' is not defined It seems that from sdaps.utils.barcode import read_barcode is missing in sdaps/recognize/buddies.py When adding it i now have : File "/usr/local/lib/python3.7/site-packages/sdaps/recognize/buddies.py", line 916, in recognize res = read_barcode(surface, matrix.mm_to_px(), AttributeError: 'cairo.Matrix' object has no attribute 'mm_to_px' I'll try to find the solution ! edit 1 : i'm not really sure of what i'm doing but it goes on, i changed  res = read_barcode(surface, matrix, x, y, width, height, "CODE128")  as i'm using 1D barcode now i have : File "/usr/local/lib/python3.7/site-packages/sdaps/model/questionnaire.py", line 42, in get_data self.sheet.data[self.id] = getattr(data, clsname)(self) AttributeError: module 'sdaps.model.data' has no attribute 'Codebox'

### benzea commented Apr 1, 2019

 Hah, did I mention that I didn't properly test this ;-) Let me cook up a fix
added a commit that referenced this issue Apr 1, 2019
 recognize: Fix matrix fetching in Codebox recognition 
 65ec5df 
There was a call to mm_to_px() that is already hidden away behind the
property in question and needs to be dropped.

See issue #2
added a commit that referenced this issue Apr 1, 2019
 model: Use Textbox storage for Codebox 
 c83f8c1 
We do not have a Codebox specific object to store recognized data.
Instead, simply use the Textbox object for this purpose.

See issue #2

### benzea commented Apr 1, 2019

 Thanks! I merged the first fix (i.e. removing the mm_to_px()) and added another commit so that Codebox is stored using the same mechanism as Textbox.

### benzea commented Apr 1, 2019

 I am not sure about CODE128 vs. QR. The easiest thing would probably be to simply accept any barcode type in there.

### jdanion commented Apr 3, 2019

 Okay, it's working fine for me. A few comments on this feature, I intend to use it for fast, fast, reliable and user-friendly medical data entry by surgeons and patients. Our IT department intends to implement an integrated system for collecting data on electronic medical records, but does not realize that our job is not just to be in front of a computer and that patients do not respond to surveys on their quality of life after surgery unless they have time before their consultation. I will now try to make barcode recognition independent of the type of barcode (our patient label barcode is Code39 and not 128.....)

### benzea commented Apr 3, 2019

 proc = subprocess.Popen(['zbarimg', '-q', '-Sdisable', '-S%s.enable' % btype.lower(), tmp], stdout=subprocess.PIPE)  Is the relevant line. Simply removing '-Sdisable' and '-S%s.enable' parameters should enable all barcode types that zbar can handle. So, I guess what we could do is allow passing None and doing exactly that then.

### jdanion commented Apr 3, 2019

 Ok i i'm trying some changes but i'm not really sure what i'm doing ... If i remove '-Sdisable', '-S%s.enable' , something is missing : File "/usr/local/lib/python3.7/site-packages/sdaps/utils/barcode.py", line 86 proc = subprocess.Popen(['zbarimg', '-q', % btype.lower(), tmp], stdout=subprocess.PIPE) ^ SyntaxError: invalid syntax When removing : '-Sdisable', '-S%s.enable' % btype.lower(), File "/usr/local/lib/python3.7/site-packages/sdaps/utils/barcode.py", line 95, in scan assert barcode.split(b':', 1)[0].replace(b'-', b'').lower() == btype.lower().encode('ascii') AssertionError Ok now some argument is missing for assert barcode.split(b':', 1)[0].replace(b'-', b'').lower() == btype.lower().encode('ascii') But it seems to be important ... # Is the /dev/stdin sufficiently portable? proc = subprocess.Popen(['zbarimg', '-q', '-Sdisable', '-S%s.enable' % btype.lower(), tmp], stdout=subprocess.PIPE) stdout, stderr = proc.communicate() os.unlink(tmp) if proc.returncode == 4: return None assert(proc.returncode == 0) barcode = stdout.split(b'\n')[0] assert barcode.split(b':', 1)[0].replace(b'-', b'').lower() == btype.lower().encode('ascii') # The following can be used to look at the images #rgb_surface.write_to_png("/tmp/barcode-%03i.png" % barcode) #barcode += 1 return barcode.split(b':', 1)[1].decode('utf-8') 

### benzea commented Apr 3, 2019

 Hehe, looks like you are not used to python :) It really is '-S%s.enable' % btype.lower() which results in e.g. -Scode128.enable. I simply didn't bother to also copy the definition of what replaces %s.

### benzea commented Apr 3, 2019

 Ah, right. Yes, you'll also need to disable the assertion. It simply double-checks that the found barcode has the expected type.

### jdanion commented Apr 3, 2019

 Hehe sure, i'm only at the beginning with python ! Thanks for your help !

### jdanion commented Apr 3, 2019 • edited

 Ok great it works now with : code39, code 128 etc thanks to some removing as i made a lot of modification, i made a new clean sdaps installation from github, it is still missing from sdaps.utils.barcode import read_barcode in buddies.py but know i still have a problem : i can only read copied barcode and not scanned barcode, maybe because of the definition une tex ? \ExplSyntaxOn \let\myquestionbegin\sdaps_qobject_begin:nnn \let\mytexthbox\sdaps_textbox_hbox:nnn \let\myquestionend\sdaps_qobject_end:n \let\mysettextboxtype\sdaps_textbox_set_type:n % Set a global overlay with a nice icon (quite likely, you will just want % to place text into the hbox below rather than just placing spacing). \sdaps_context_set:n { codebox = { centered_text = {etiquette % \begin{tikzpicture}[yscale=-0.1, xscale=0.1] % \path[draw=black,fill=black,stroke=] (-1,0) % -- (-1,5) -- (4,5) -- (4,0) -- cycle(7,0) -- (7,5) -- (12,5) -- (12,0) -- cycle(0,1) -- (3,1) -- (3,4) % -- (0,4) -- cycle(8,1) -- (11,1) -- (11,4) -- (8,4) -- cycle(1,2) -- (1,3) -- (2,3) -- (2,2) -- cycle(5,2) -- % (5,3) -- (6,3) -- (6,2) -- cycle(9,2) -- (9,3) -- (10,3) -- (10,2) -- cycle(5,4) -- (5,6) -- (2,6) -- (2,7) % -- (6,7) -- (6,4) -- cycle(0,6) -- (0,7) -- (1,7) -- (1,6) -- cycle(7,6) -- (7,7) -- (8,7) -- (8,6) -- % cycle(-1,8) -- (-1,13) -- (4,13) -- (4,8) -- cycle(5,8) -- (5,13) -- (6,13) -- (6,8) -- cycle(7,8) -- (7,9) % -- (8,9) -- (8,10) -- (7,10) -- (7,13) -- (8,13) -- (8,11) -- (9,11) -- (9,10) -- (10,10) -- (10,9) -- (9,9) % -- (9,8) -- cycle(10,9) -- (12,9) -- (12,8) -- (10,8) -- cycle(0,9) -- (3,9) -- (3,12) -- (0,12) -- % cycle(1,10) -- (1,11) -- (2,11) -- (2,10) -- cycle(11,10) -- (11,11) -- (12,11) -- (12,10) -- cycle(11,11) -- % (10,11) -- (10,12) -- (9,12) -- (9,13) -- (12,13) -- (12,12) -- (11,12) -- cycle; % \end{tikzpicture} }, } } \ExplSyntaxOff %\textbox{0cm}{} \myquestionbegin{barcode}{text}{text} \mysettextboxtype{codebox} % Note that we use hspace + vrule for sizing here, that is a bit weird but % a reasonable method of setting a size \mytexthbox{}{1bp}{ \hspace{5.6cm} \vrule width 0pt height 3.3cm depth 0cm } \myquestionend{barcode} i changed heigh and depth in order to fit the document
added a commit that referenced this issue Apr 3, 2019
 recognize: Add missing import of barcode reading routine 
 4ebed08 
See issue #2

### jdanion commented Apr 3, 2019

 I have some new facts. When I want to scan with an added patient label: failure. When I add a barcode in copy and paste on a clean stamp.pdf file: it works. Also when I print this file and then scan it again: sdaps recognizes the barcode. Is this due to a matrix problem? Between the entire questionnaire matrix and the codebox matrix?

### benzea commented Apr 3, 2019

 Could you check that the barcode from the first file looks reasonable (in the .tif file in the project or UI)? Maybe the scan is just bad or low quality for some reason?

### jdanion commented Apr 3, 2019

 The barcode looks good, there is some text before the barcode on the patient label, i tried to erase it after scan but doesn't works. When i try online barcode detector it works, and the same for bottom ones. I'll try to magnify the barcode size

### benzea commented Apr 3, 2019

 Nah. More likely something else is going wrong. Like e.g. the matrix being applied in the wrong way or I made a horrible mistake and we are looking at the wrong area. Two things you can do: Run sdaps annotate and check that the area is correct (I am going to have a look at the code now) Look at barcode.py there is a comment at the bottom, if you enable those two lines you can check whether the cut out area is sane on that side.

### benzea commented Apr 3, 2019

 Hmm, 1. looks entirely correct (by the way, I am amazed you are actually using the whole override/overlay stuff …). Oh, and 2. is missing quite a lot of code …

### benzea commented Apr 3, 2019

 This should fix the barcode image writing stuff: show-images.patch.txt (I will never understand why github doesn't like .patch …)

### benzea commented Apr 3, 2019

 But, AFAICT, everything is working as expected. So maybe it is some other issue, possibly even that the barcode is destroyed by the import or so?

### jdanion commented Apr 4, 2019

 I have one success and one fail for the same document but with some rotation of the label. pictures of the barcode are well recorded in the /tmp, and the rotated one is also still rotated.

### benzea commented Apr 4, 2019

 Do you think the rotation is the issue? The image is not being de-skewed for barcode recognition. I always assumed that this would actually decrease the quality rather than improve it.

### jdanion commented Apr 4, 2019

 I have done a LOT of label sticking / scanning / barcode recognition today, and it only works when the barcode is horizontal. The thing is, it works:) I am very happy but maybe for some cases it will not recognize if the label is not pasted with surgical precision :)

### benzea commented Apr 5, 2019

 OK, no idea about that unfortunately. I guess zbar is not very robust with regard to rotation then; but I am not sure whether that means we should add workarounds or something into SDAPS … If this is an issue, we would need to a collection of samples that one can test the barcode recognition against.

### jdanion commented Aug 5, 2019

 Another idea that would need some help as i can't find where to implement it : Where should i add some code to extract the image of a codebox like csv export --images. Is adding "image_writer = self.obj.question.questionnaire.csvdata.image_writer" somewhere a good start ?