Resize and vertically align a scan image with its original

Visuals, audio, animation. Blended, not stirred. If LiveCode is part of your rich media production toolbox, this is the forum for you.

Moderators: Klaus, FourthWorld, heatherlaine, robinmiller, kevinmiller

Post Reply
trevix
Posts: 425
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Resize and vertically align a scan image with its original

Post by trevix » Sun Mar 24, 2019 6:28 pm

Given an A4 original image (say jpeg) and its copy, made from the original, with a scanner.
Given the feeding mechanics of the scanner probably the copy will be slightly rotated and scaled.

Is Livecode suitable to resize and realign the copy with its original using, I guess, a couple of reference lines on each and working the math on the ImageData property of the copy?

That is, is this going to be so time consuming in LC as to require a C++ external?

The objective would be to compare the original with a pencil filled copy, for example with check mark boxes.

Thanks
Trevix
Trevix

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1958
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: Resize and vertically align a scan image with its original

Post by [-hh] » Mon Mar 25, 2019 1:31 pm

Sample Stacks > DePerspective/Undistort Images 1.0.1
or
http://livecodeshare.runrev.com/stack/824/
shiftLock happens

trevix
Posts: 425
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Resize and vertically align a scan image with its original

Post by trevix » Thu Apr 04, 2019 1:04 pm

On my quest to do a standalone that can detect wrong check marks in scanned homework (multiple answers) I finally gave up on trying to detect the position of the checkboxes (it would be very time consuming anyway).
I found anyway that the auto feeder of my Epson scanner is very good in aligning pages

For anyone that could be interested, I got a stack that works (pretty well).
- Load the unfilled scan of the A4 homework.
- Load the filled (pencil) scan of the homework
- manually select the positions of the square boxes and check/uncheck the correct answers
- run the script ("Check")
  • 1 hide the red boxes (not the check marks) and put a snapShost of the source into another image container
    2 convert to B&W each red area in source var
    3 detect difference from source and target pixels
    4 analyze the results and put a red check mark on wrong answers in the target
    5 you can then print the corrected homework (not done yet)
This is the main script of the stack (which is attached, already with two documents on it. Just press "Check")
Feel free to make useful suggestions !!!

Code: Select all

--This command loops through each pixel of the image and calls a function that compare
-- the grey values of neighboring pixels.
command ConfrontaImmagini  
     put the milliseconds into tTime
     local  tX, tY, tImagePosition
     # set up the global variables
     delete global gTargetArray
     delete local sSourceArray
     put empty into tGreyOriginal
     put empty into tGreyTarget
     put thumbPosition of scrollbar the "Scrollbar" into tThreshold
     
     --cleanup previous
     CleanUpTarget
     # make a copy of the image that is to be processed without red boxes
     --doing it to var does not work, the content seems to be different
     --put TakeAsnapShot() into sSourceCleanVar
     
     --so, put the snapshot in another image container
     get TakeAsnapShot()
     put the imageData of image "SourceClean" into sSourceCleanVar
     --loop for each box
     repeat for each line tKey in the keys of sSourceArray
          put 1 into tCounter
          put empty into  tGreyOriginal
          put empty into tGreyTarget
          # loop through every pixel of the snapshot image and check the grey level of each
          repeat with tY =  sSourceArray[tKey]["top"] to sSourceArray[tKey]["bottom"] - 1
               repeat with tX = sSourceArray[tKey]["left"] to sSourceArray[tKey]["right"] - 1
                    put (tX + tY * sXsize) * 4 into tImagePosition
                    put tGreyOriginal + ConvertToBW(tImagePosition,sSourceCleanVar) into tGreyOriginal
                    put tGreyTarget + ConvertToBW(tImagePosition,sTargetImageVar) into tGreyTarget
                    add 1 to tCounter
               end repeat
          end repeat
          --0= black 255= white
          put round(tGreyOriginal/tCounter) into tGreyOriginal
          put round(tGreyTarget/tCounter) into tGreyTarget
          if tGreyOriginal < (tGreyTarget  - tThreshold) then
               put 1 into gTargetArray[tKey]["value"]
               --put tGreyOriginal into gTargetArray[tKey]["GrayOrig"]
               --put tGreyTarget into gTargetArray[tKey]["GrayTarg"]
          else
               put 0 into gTargetArray[tKey]["value"]
               --put tGreyOriginal into gTargetArray[tKey]["GrayOrig"]
               --put tGreyTarget into gTargetArray[tKey]["GrayTarg"]
          end if
     end repeat
     --mark the correct answers
     repeat for each line tKey in the keys of gTargetArray
          if  gTargetArray[tKey]["value"] = 1 then
               clone  btn "BtnCheckCorrect"
               set the name of it to "BtnCheckCorrect" && tKey
               put the loc of btn "BtnCheck" of group ("CheckRect"  && tKey) into tLoc
               add  (the left of image "TargetImage" - the left of image "SourceImage") to item 1 of tLoc
               set the loc of it  to tLoc
          end if
     end repeat
     put "Timer(sec):" && (the milliseconds - tTime)/1000 into fld "FldTimer"
     beep
     answer "Finito"
end ConfrontaImmagini

--convert the image to Black & White
function ConvertToBW tImgPosition, pTheImage
     put charToNum (char (tImgPosition + 2) of pTheImage) into tHowGrey
     if tHowGrey < 200 then
          return 0 --black
     else
          return 255 --white
     end if
end ConvertToBW

--hide all red boxes and take a snapshot with correct checkmark
function TakeAsnapShot
     lock screen
     put the childControlNames of group "groupRects" into tList
     repeat for each line tLine in tList
          if "checkRect" is in tLine and tLine <> "checkRect" then
               --get the rect of the choosen area
               put word 2 of tLine into tnum
               put the rect of graphic "checkRect" of group tLine into tLimitRect
               put (item 1 of  tLimitRect - the left of image "SourceImage") into sSourceArray[tnum]["left"]
               put (item 3 of tLimitRect - the left of image "SourceImage")  into sSourceArray[tnum]["right"]
               put (item 2 of  tLimitRect - the top of image "SourceImage") into sSourceArray[tnum]["top"]
               put (item 4 of tLimitRect - the top of image "SourceImage")  into sSourceArray[tnum]["bottom"]
               hide graphic "checkRect" of group tLine of group "groupRects"
               if the visible of btn "BtnCheck" of group tLine then
                    put 1 into sSourceArray[tnum]["Value"]
               else
                    put 0 into sSourceArray[tnum]["Value"]
               end if
          end if
     end repeat
     --now shapshot
     put the rect of image "SourceImage" into tRect
     --export snapshot from rect tRect of this card to tSourceClean as PNG
     export snapshot from rect tRect of this card to image "SourceClean" as PNG
     repeat for each line tLine in tList
          if "checkRect" is in tLine and tLine <> "checkRect" then
               show graphic "checkRect" of group tLine of group "groupRects"
          end if
     end repeat
     return tSourceClean
end TakeAsnapShot
Attachments
ScanTest.zip
(61.35 KiB) Downloaded 4 times
Trevix

Post Reply

Return to “Rich Media”