3

I took the code in the answer https://stackoverflow.com/a/10374811/4828720 from Image transformation in OpenCV and tried to adapt it to an image of mine.

My source image: My source image

In it, I identified the pixel coordinates of the centers of the checkered bricks, illustrated here:

Source points

My target resolution is 784. I calculated the destination coordinates of the pixels. My resulting code is this:

import cv2
from scipy.interpolate import griddata
import numpy as np

source = np.array([
    [315, 15],
    [962, 18],
    [526, 213],
    [754, 215],
    [516, 434],
    [761, 433],
    [225, 701],
    [1036, 694],
], dtype=int)

destination = np.array([
     [14, 14],
     [770, 14],
     [238, 238],
     [546, 238],
     [238, 546],
     [546, 546],
     [14, 770],
     [770, 770]
], dtype=int)

source_image = cv2.imread('frames.png')

grid_x, grid_y = np.mgrid[0:783:784j, 0:783:784j]
grid_z = griddata(destination, source, (grid_x, grid_y), method='cubic')
map_x = np.append([], [ar[:,1] for ar in grid_z]).reshape(784,784)
map_y = np.append([], [ar[:,0] for ar in grid_z]).reshape(784,784)
map_x_32 = map_x.astype('float32')
map_y_32 = map_y.astype('float32')
warped_image = cv2.remap(source_image, map_x_32, map_y_32, cv2.INTER_CUBIC)
cv2.imwrite("/tmp/warped2.png", warped_image)

If I run this, none of the source points end up at their intended destination, but I get a warped mess instead. I added the destination points on top here:

My result

Where am I going wrong? I noticed that my grid and map arrays are not as nicely distributed as the ones in the example. Do I have too few points? Do I need them in a regular grid? I tried only using the four points in the outer corners with no luck either.

Community
  • 1
  • 1
bugmenot123
  • 1,069
  • 1
  • 18
  • 33

2 Answers2

2

The whole problem was that I, again, got confused by numpy's row/column indexing instead of x/y. Someone in the #opencv IRC channel pointed it out. My source and destination arrays had to have their columns switched:

source = np.array([
    [15, 315],
    [18, 962],
    [213, 526],
    [215, 754],
    [434, 516],
    [433, 761],
    [701, 225],
    [694, 1036],
], dtype=int)

destination = np.array([
     [14, 14],
     [14, 770],
     [238, 238],
     [238, 546],
     [546, 238],
     [546, 546],
     [770, 14],
     [770, 770]
], dtype=int)

Then it worked as intended (ignore the ugly warping, this was a simplified list of coordinates to find the bug):

enter image description here

bugmenot123
  • 1,069
  • 1
  • 18
  • 33
1

If you only have 8 points for warping an no real distortion in your image, I'd suggest to use perspective transformation as described here.

The link you are quoting tries to eliminate additional distortions which lead to non-straight lines, but all lines in your image are straight.

Code would look like:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('image.png')
rows,cols,ch = img.shape

pts1 = np.float32([
    [315, 15],
    [962, 18],
    [225, 701],
    [1036, 694],
], dtype=int)

pts2 = np.float32([
     [14, 14],
     [770, 14],
     [14, 770],
     [770, 770]
], dtype=int)

M = cv2.getPerspectiveTransform(pts1,pts2)

dst = cv2.warpPerspective(img,M,(784,784))

plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

enter image description here

tfv
  • 6,016
  • 4
  • 36
  • 67
  • I meant to include a paragraph saying that perspective correction is not enough. It almost is, but I want more. Sorry and thanks! Here http://i.imgur.com/Is5rwrq.png are some black bars drawn over your result, as you can see there is curved distortion in some parts of the image. My 8 points are actually just a simplification, in reality I would use many more. I am just lost as to why it does not work at all right now. – bugmenot123 May 15 '16 at 11:49
  • In that case I'd suggest that you detect each single intersection of lines. There is a briliant example with source code here: http://stackoverflow.com/questions/10196198/how-to-remove-convexity-defects-in-a-sudoku-square/11366549#11366549 – tfv May 15 '16 at 11:57
  • That was my plan but it did not work out of the box for my imagery (my grid is not nearly as distinguished) plus I thought remap would be worth a try anyways. – bugmenot123 May 15 '16 at 15:17