Pharmacode Reading

I am trying to read 1D Pharma Codes with the Common Vision Blox Barcode tool. The code looks nice enough, contrast is good, yet I don’t get any results ever from the barcode tool:

:confused:

Reading 1D Pharmacodes can be tricky (or, to put it more precisely: correctly configuring the Barcode tool for 1D Pharmacode can be tricky…)

1D Pharmacodes have originally been specified by the company Laetus for very simple readers based on photo diodes moving over a printed stripe code. The definition of the 1D Pharmacode lacks a few features that are generally defined for other 1D codes such as consistency markers or check sum - this makes reading the code more difficult because you will need to know the reading direction before reading it (for example your code may be read left to right or right to left; both directions yield a plausible result and unless you know the code’s content already, the “correct” result cannot be determined just by looking at the result). On top of that, the widths of the code’s bars have only been defined in real world coordinates (mm) and to read them unambiguously you will need to configure the correct mapping from pixels to mm.

Configuring :cvb: Barcode for 1D Pharmacodes

(this description may also be found in the Applications section of the Barcode.chm file)

  1. Disable all other symbologies and make sure the 1D Pharmacode stands alone on your image.
    1D Pharmacodes should usually be read alone, meaning that the area of interest should only contain the 1D Pharmacode, a reasonably sized quiet zone (typically around 5 mm) and nothing else. As the Pharmacode does not define consistency check features the reader may easily be misled by other 1D codes or even background patterns.
  2. Define the reading direction.
    As stated above, reading Pharmacodes in the wrong direction will yield plausible results, so the direction in which the code needs to be read needs to be known prior to reading it.
  3. Define the scale.
    For reading 1D Pharmacodes the mapping of pixels to millimeters must be known at least approximately. The definition is actually quite simple: Measure the width of the broader bars in pixels. For a regular size 1D Pharmacode these are supposed to be 1.5 mm in size.

For your image

  • Criterion 1 can be easily ticked off - simply create your Barcode configuration as one that is empty (see code below) and then activate only the 1D Pharmacode. The image itself is nice enough, i.e. the quiet zone is not violated and big enough.
  • Criterion 2: That’s really up to you to decide. When reading your image left-to-right, the result is 49, when reading right-to-left the result is 40
  • Criterion 3: The width of the broader bars (#2 and #5) is roughly 22 pixels. In millimeters this is supposed to be 1.5, which means the scale factor is about 1.47 and for :cvb: barcode we need to multiply this by 100, giving us a factor of 147.

This can be coded like this with the :cvb: C API

// assumptions:
// - img refers to a valid CVB image like in the original post
auto config = CvcBcCreateConfiguration(CVC_BC_DENY_ALL);
// from the parameters below only the 147 and the run direction are specific to 
// this code; the others are the recommended default values
CvcBcSetPharmacodeEx(config, true, CVC_BC_PHARMACODE_RUN_DIRECTION_RIGHT, // ... or _LEFT
  4, 16, 100, 50, 147, 10, false, CVC_BC_PHARMACODE_TOLERANCE_EXTENDED,
  CVC_BC_PHARMACODE_SKEW_NONE);
char code[256] = { 0 };
CVC_BC_INFO info;
CvcBcDecodeBarcode(img, 0, nullptr, CVC_BC_OMNI, config, code, 256, &info, sizeof(info));

In the upcoming CVB.Net API the same result can be achieved as follows:

using Stemmer.Cvb;
using Stemmer.Cvb.Barcode;
using Stemmer.Cvb.Barcode.Configuration;

namespace PharmacodeReading
{
  class Program
  {
    static void Main(string[] args)
    {
      var img = new CvbImage(@"<path to the image from the original post>");
      var bc = new ReaderConfig(ReaderInitialization.ReadNone);
      bc[Symbology.PharmaCode] = new PharmaCode()
      {
        Direction = PharmaCodeRunDirection.Right,
        PixelReference = 145
      };
      var res = Reader.Execute(bc, img.Planes[0]);
    }
  }
}
1 Like

Now that you mention it: Yes, it’s there in the documentation…