0

I'm trying to print out QR codes onto the surface of water bottles using matlab. However, the QR bottles cannot be recognized because of the curved surface of the bottle, and the therefore deformed shape of the QR codes.

I was wondering what mathematical equation I might have to apply to deform the picture (for both the general geometry of the picture, and the spacing deformation inside the picture), so that when printed onto a cylindrical surface, it seems like its on a flat surface to a camera.

Thanks!

A. Rapoport
  • 113
  • 7
  • 1
    Cool question. I think you are looking for *"anamorphic projection"*. Here are some links while I think about how to do it in software https://www.youtube.com/watch?v=crfpdWefxBY and also https://makezine.com/projects/draw-distorted-pictures/ – Mark Setchell Jan 27 '20 at 14:55
  • 1
    [This question](https://stackoverflow.com/questions/32974007/unwrap-picture-of-a-half-cylinder-in-matlab) may have some ideas for you. – beaker Jan 27 '20 at 18:11

2 Answers2

1

I had some success with this and though it doesn't use Matlab, it may give you, or someone else an idea on a possible way to get started.

I generated a QR code with qrencode in Terminal like this:

qrencode -o qr.png -d 300 'http://www.thesetchells.com'

enter image description here

I resized that to 500x500 and then generated a "displacement map" which is just a linear gradient with a contrast stretch created to match the size of the QR code. I used ImageMagick in Terminal, but obviously you can use Matlab or other tools:

enter image description here

I then applied the displacement map to my QR code like this:

convert qr.png map.png -fx 'p{v*w,j}' result.png

And got a distorted QR code, which I printed and wrapped round a large bottle and my iPhone was able to read it.

Anthony Thyssen has some very useful information on "displacement maps" here.

miken32
  • 42,008
  • 16
  • 111
  • 154
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
0

So I've tried an approach to my problem using the basic "car.jpg" image included in Matlab.

So far, I've taken a square part of the car picture, and wrapped it around the surface of part of a cylinder.

Here is my code:

close all, clf, clear all
%% Creating cylinder
r = 6;    %centimeter
h = 25;     %centimeter

[X,Y,Z] = cylinder(r,100);
x = X(:,1:ceil(length(X)/3));
y = Y(:,1:ceil(length(Y)/3));
z = Z(:,1:ceil(length(Z)/3));

%% Plotting cylinder surface
figure(1), clf
h = surf(x,y,z); hold on

axis([-r r -r r]*2.2)
plot3([-r -r], get(gca,'ylim'), [0 0]);
plot3([r r], get(gca,'ylim'), [0 0]);
plot3(get(gca,'xlim'), [-r -r], [0 0]);
plot3(get(gca,'xlim'), [r r], [0 0]);

xlabel('x');
ylabel('y');
zlabel('z');

rotate3d on
axis vis3d

%% Car image
img = imread('car.jpg');
img = imrotate(img,180);
figure(2), clf
%imshow(img(1:340, 1:340, :));
imagesc(img(1:340, 1:340, :));


figure(), clf
warped_plot = warp(x,y,z,img(1:340, 1:340, :))

The next step could be to now project that warped image onto a flat surface (but I'm not sure how to do that mathematically, nor have I found a in-built Matlab function to do this).

Another possibility I was hoping to get feedback on, is to find a mathematical relation between corresponding horizontal points on the flat and cylindrical image, and then to apply the inverse of that equation to the flat image, so that once it is printed out and stuck onto a cylindrical surface it appears flat.

A. Rapoport
  • 113
  • 7