d-fens_
d-fens_

Reputation: 77

Detect and correct bended images of digitized super8 frames using opencv

i am using a photoscanner and DIY transport device to get high quality scans of old Super/Normal 8 films. I wrote the free software that automates the transport of the film using a stepper motor over the scanner pane and do the scanning of the strip; free software exists to extract the frames out of that strip and allows generating a movie out of it. We put up a wiki describing the whole process and software.

The problem i'd like to solve are bended/twisted scans of the strips caused by the film sitting not 100% flat in the filmguide or even jumping out of it.

Here is a example image of a bend stripe:

What would be the best approach to detect the bending using the geometry of the sprocket holes or frame borders and getting a aligned image? Often the errors builds up gradually towards the beginning/end of the strip where the film is entering/leaving the filmguide, which can lead to jumps in the output film.

I'm favouring a strip based correction over a frame by frame correction but i don't know what would be the most promising approach to detect if there is a bending and then correct it.

Any input of you gurus would be great!

Upvotes: 1

Views: 705

Answers (2)

Nick2222
Nick2222

Reputation: 28

It's an old question but maybe someone else has a similar problem. The first thing would be, as Lamar said, to find the contours of the frame, like with OpenCV's findContours(). Get the contour you want matching some conditions, for example the one with a centroid more or less in the center of the image and with the biggest area. Then, get the four extreme points: topleft, topright, bottomleft, bottomright, that could be the most distanced from the centroid, and apply a perspective transformation using these extreme points:

#get max distances between points. Coordinates in [x,y]
height_dst = max((bottomleft[1]-topleft[1]), (bottomright[1]-topright[1]))
width_dst = max((topright[0]-topleft[0]), (bottomleft[0]-bottomleft[0]))

#destination points
#(topleft,topright,bottomleft,bottomright) x (x,y)
dst_pts = [[0,0], [width_dst,0], [0,height_dst], [width_dst,height_dst]] 

#transformation matrix
or_pts = [topleft,topright,bottomleft,bottomright]
transM = cv2.getPerspectiveTransform(np.float32(or_pts), np.float32(dst_pts))

#transform image
img = cv2.warpPerspective(img,transM,(width_dst,height_dst))

Upvotes: 0

Lamar Latrell
Lamar Latrell

Reputation: 1669

A start would be finding the image shear - those sprocket holes look like very good signal to noise ratio markers for the amount you need to correct by. Specifically the angle to vertical that the sides of them make.

Maybe there is something better, but I've been using contours lately, the basics:

  • Threshold/Canny detect until they are all that are left
  • Find contours
  • Use moments to find the centroids (which you'll then know how much to move the film up and down by)
  • Use moments or maybe the contour points themselves to (somehow) find the shear angle - suggest using the 'CV_CHAIN_APPROX_SIMPLE' tag in findContours ...

Maybe there is a better way :) and as for the slight curve - hrrrm, no idea

Upvotes: 0

Related Questions