[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Intelligently crop a scanned image

Posted on 2010-09-15
2
Medium Priority
?
569 Views
Last Modified: 2016-09-30
I've managed to talk to my scanner and pull in an image, in this case it will be ID cards or passports etc,
but now I need to crop away the background of the scan (which is white or black).
It doesn't need to be a perfect crop, in fact I think it will be a 'suggested crop' and the user can check if it's right and approve it.
0
Comment
Question by:rfwoolf
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 24

Assisted Solution

by:jimyX
jimyX earned 300 total points
ID: 33684420
I am not sure if there is a way that makes you able to detect the white or dark space in a scanned image, but I have another idea which is by matching between a blank scanning and the target scanning you will get the difference highlight, i.e: you can create a standard stored image of the scanner (blank scanning), and whenever you want to make a scan just match between the stored image and the new scanned image and then by detecting the difference between them you can have your target area highlighted. I did not try this with scanner but theoretically it should work.

Again from efg Lab:
function Min(a, b: Longint): Longint;
begin
  if a > b then
    Result := b
  else
    Result := a;
end;

function Max(a, b: Longint): Longint;
begin
  if a > b then
    Result := a
  else
    Result := b;
end;

function ScanImages(previous:TBitmap;current:TBitmap;var Changed:TRect):Boolean;
var
  ix, iy, idiff : INTEGER;
  minx, maxx, miny, maxy : INTEGER;
  tempPixel1, tempPixel2 : TColor;

function ProbablyNoise (xPos, yPos : INTEGER) : BOOLEAN;
const
  noiseThreshhold = 3;
var
  jx, jy : INTEGER;
  nDiff : INTEGER;
  nearPixel1, nearPixel2 : TColor;
begin
  nDiff := 0;
  for jx := Max(0,xPos-2) to Min(xPos+2,Form1.Blank.Width) do
    begin
      for jy := Max(0,yPos-2) to Min(yPos+2,Form1.Blank.Height) do
        begin
          nearPixel1 := Form1.Blank.Canvas.Pixels[jx,jy];
          nearPixel2 := Form1.ScannedImage.Canvas.Pixels[jx,jy];
          if (nearPixel1 <> nearPixel2) then
            INC(nDiff);
        end {FOR};
    end {FOR};
  if nDiff > noiseThreshhold then
    result := false
  else result := true;
end {ProbablyNoise};

begin
//  RESULT :=  FALSE;
  { Make sure they are the same shape }
  if (previous.Height <> current.Height)or(previous.Width  <> current.Width) then
    begin
      RESULT := FALSE;
      EXIT;
    end {IF};

  { We'll work with the pixels because we want to bounding TRect }
  minx := previous.Width; maxx := -1;
  miny := previous.Height; maxy := -1;
  iDiff := 0;
  for iy := 0 to previous.Height-1 do
    begin
      for ix := 0 to previous.Width-1 do
        begin
          tempPixel1 := previous.Canvas.Pixels[ix,iy];
          tempPixel2 := current.Canvas.Pixels[ix,iy];
          if (tempPixel1 <> tempPixel2) and not ProbablyNoise(ix,iy) then
            begin
              inc(iDiff);
              minx := Min(minx,ix);
              maxx := Max(maxx,ix);
              miny := Min(miny,iy);
              maxy := Max(maxy,iy);
            end {IF};
        end {FOR};
    end {FOR};
  if (iDiff <= 0) then
    RESULT := FALSE
  else
    begin
      result := TRUE;
      Changed.Left := minx;
      Changed.Right := maxx;
      Changed.Top := miny;
      Changed.Bottom := maxy;
    end {IF};
end {ScanImages};

procedure TForm1.Button1Click(Sender: TObject);
var
  A:TRect;
begin
if ScanImages(Blank.Picture.Bitmap, ScannedImage.Picture.Bitmap,A) then
  begin
    ScannedImage.Canvas.DrawFocusRect(A);
  end;
end;

Open in new window

0
 
LVL 25

Accepted Solution

by:
epasquier earned 1700 total points
ID: 33684897
Here is a matching color function based on the RGB value, with a tolerance value
That tolerance value is the maximum "distance"
function ColorMatch(C1,C2:TColor;Tolerance:Single):Boolean;
Var
 R1,B1,C1:Byte;
 R2,B2,C2:Byte;
begin
 C1:=ColorToRGB(C1); 
 R1:=C1 And $FF;
 G1:=(C1 SHR 8)And $FF;
 B1:=(C1 SHR 16) And $FF;
 C2:=ColorToRGB(C2);
 R2:=C2 And $FF;
 G2:=(C2 SHR 8)And $FF;
 B2:=(C2 SHR 16) And $FF;
 Result:= Sqrt(sqr(R1-R2)+ (sqr(G1-G2)+(sqr(B1-B2))<=Tolerance;
end;

Open in new window

0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question