This challenge is very similar to the issues I've encountered in my barcode system. My answer is a generalized description of the method I use.
I'd start by dividing the image into a grid, where a single character cell would fit within a single grid cell. This would make it that any character would be guaranteed to fit within a 2x2 grid cell, no matter how the grid overlays the image.
Convert the image into dots. Dots are identified by local identification using a small area of pixels.
assign each dot a grid cell number. this should be something easy like x/y location divided by 32 pixels cell ((y/32)*(width/32))+(x/32)
Keep a count of dots per grid cell and when all the dots are identified, sort the dot table by grid number and build an index by displacement in the table and number of elements.
If the resolution varies, sample some cells with lots of dots to determine distance between cell pairs.
Look though the cells row by row, but examine each cell using a 2x2 cell group. This way, any dot in the cell being tested, is guaranteed to be matched to a paired dot (if one exists). By using the grid dots only need to be matched to dots local to each other, so while the image may have thousands of dots, individual dots only need to try to match to 1-10 dots.
Pairing dots will create duplicates, which can either be prevented while matching or purged later.
At this point is where you would need to match the dots to Braille. Horizontal pairs of pairs and vertical pairs of pairs should be able to start lining up the Braille text.
Once the lines are aligned, the speck table would then be rotated into the text alignment determined. The pairs would be put into alignement, then from the position of the pair, unmatched specks could be added by matching the grid location of the pair to unpaired dots in the dot table.