(* * Copyright (c) 2005, 2006, 2007 Abram Hindle * * This file is part of CaptchaBreaker * CaptchaBreaker is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * Foobar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . *) (* Machine Learning Shit, Extractors etc. *) open Shape;; open Images;; open OImages;; open Fft;; open Abez;; (* Features we want to add, * count pts * centroid * x mid point * y mid point * aspect * sum columns * FFT * End points * loops *) let fft = new jfft;; let b_w_h h = let height = h#height in let width = h#width in (width,height) ;; let hget bmp x y = let c = bmp#get x y in 1.0 -. (float_of_int (c.r )) /. 255. ;; let cnt_pts b = let (w,h) = b_w_h b in let o = ref 0. in for y = 0 to (h - 1) do for x = 0 to (w - 1) do o := !o +. (hget b x y) done; done; ((!o),(float_of_int (w*h))) ;; (* centroid, and normalized centroid *) let centroid b = let (w,h) = b_w_h b in let xo = ref 0. in let yo = ref 0. in let fi = float_of_int in for y = 0 to (h - 1) do for x = 0 to (w - 1) do let g = hget b x y in yo := !yo +. (fi y) *. g ; xo := !xo +. (fi x) *. g ; done; done; let fh1 = fi (h - 1) in let fw1 = fi (w - 1) in yo := !yo /. (fh1) -. fh1 /. 2.0; xo := !xo /. (fw1) -. fw1 /. 2.0; (!xo , !yo, (!xo /. (fw1 /. 2.0)), (!yo /. (fh1 /. 2.0))) ;; let normalized_cnt_pts b = let (points,total_points) = cnt_pts b in points /. total_points ;; let get_aspect (_,_,x,y) b = let (w,h) = b_w_h b in let fw = (float_of_int ( w - 1)) in let fh = (float_of_int ( h - 1)) in (y *. fh +. fh /. 2.0) /. ( x *. fw +. fw /. 2.0) ;; let resample_to w h bmp = let (hw,hh) = b_w_h bmp in let arr = Array.create (w * h) 0. in let arrget i = arr.(i) in let arradd i x = arr.(i) <- arr.(i) +. x; in let index x y w = y * w + x in for y = 0 to (hh - 1) do for x = 0 to (hw - 1) do let y' = y * (h - 1) / (hh - 1) in let x' = x * (w - 1) / (hw - 1)in let dx = hget bmp x y in arradd (index x' y' w) dx; done; done; arr ;; let normalized_subset w h bmp = let index x y w = y * w + x in let arr = resample_to w h bmp in let arrdiv i x = arr.(i) <- arr.(i) /. x; in let arrget x y= arr.(index x y w) in for y = 0 to (h - 1) do let total = ref 0. in for x = 0 to (w - 1) do total := !total +. (arrget x y) done; if ((!total *. !total) > 0.0000000001) then for x = 0 to (w - 1) do arrdiv (index x y w) !total; done; done; Array.to_list arr ;; let resample_to_aspect w h bmp = let (hw,hh) = b_w_h bmp in let fi = float_of_int in let l = w * h in let arr = Array.create l (0.,0) in let outarr = Array.create l 0. in let index x y = x + w * y in let aspect = (fi hh) /. (fi hw) in let outset x y v = outarr.(index x y) <- v in let arrget x y = arr.(index x y) in let arradd x y dx = let i = index x y in if (i < l) then let (v,c) = arr.(i) in arr.(i) <- (v+.dx,c+1) in let xw = int_of_float ((fi (w)) /. aspect) in let yh = int_of_float ((fi (h)) *. aspect) in let f h' w' = let yoff = (h - h')/2 in let xoff = (w - w')/2 in let h = h' in let w = w' in (* print_endline ((string_of_int h) ^ " " ^(string_of_int w)); *) for y = 0 to (hh - 1) do for x = 0 to (hw - 1) do let y' = yoff + y * (h - 1) / (hh - 1) in let x' = xoff + x * (w - 1) / (hw - 1)in let dx = hget bmp x y in arradd x' y' dx; done done in let _ = if (aspect = 1.0) then f h w else if (aspect < 1.0) then f yh w else f h xw in (* now normalize again *) for y = 0 to (h - 1) do for x = 0 to (w - 1) do let (v,c) = arrget x y in if (c > 0) then outset x y (v /. (float_of_int c)) done; done; Array.to_list outarr ;; let get_columns n l = let arr = Array.create n 0. in Abez.iteri (fun i x -> arr.(i mod n) <- arr.(i mod n) +. x ) l; Array.to_list arr ;; let buffer_to_linear bmp = let (w,h) = b_w_h bmp in let arr = Array.create (w * h) 0. in for y = 0 to (h-1) do for x = 0 to (w-1) do arr.(x + y * w) <- hget bmp x y done done; arr ;; let run_fft_on lin_arr n st en = let imag = Array.create n 0. in let real = Array.create n 0. in let imago = Array.create n 0. in let realo = Array.create n 0. in for i = st to en do real.(i - st) <- lin_arr.(i); done; fft#fft_f real imag realo imago; (realo,imago) ;; let get_fft min' max' w h samples = let lin_arr = Array.of_list samples in let run_fft_on = run_fft_on lin_arr in let arrl = h * w in let rec find_next_two n s = if (s >= n) then s else (find_next_two n (s*2)) in let max2 = find_next_two (min arrl max') 1 in let rec powers_of_two = function n when n >= min' -> n :: (powers_of_two (n/2)) | _ -> [] in let pwrs = powers_of_two max2 in let lists = List.flatten ( List.map ( fun m -> let max = arrl / m in List.flatten ( Abez.for_map ( fun i -> let start = m * i in let ending = start + m - 1 in let ending = min (arrl-1) ending in let (r,i) = run_fft_on m start ending in Array.to_list r ) max ) ) pwrs ) in lists ;; let get_avg_fft max2 h w samples = let lin_arr = Array.of_list samples in let run_fft_on = run_fft_on lin_arr in let arrl = h * w in let avg = Array.create max2 0. in let max = arrl / max2 in Abez.fori ( fun i -> let start = max2 * i in let ending = start + max2 - 1 in let ending = min (arrl-1) ending in let (r,i) = run_fft_on max2 start ending in Abez.add_array avg r; ) max; Array.to_list avg ;;