# # OpenCV (www.opencv.org) # # from RCS::Common require 'rcs-common/trace' require 'ffi' unless RbConfig::CONFIG['host_os'] =~ /mingw/ require 'opencv' include OpenCV end module RCS module OCR =begin typedef int (*DetectFace_t)(char *, char *, int); HMODULE hmod = LoadLibrary(L"Face.dll"); DetectFace_t detect_faces = (DetectFace_t)GetProcAddress(hmod, "detect_faces"); faces = detect_faces(input, "haarcascade_frontalface_default.xml", 1); =end module FACE extend FFI::Library if RbConfig::CONFIG['host_os'] =~ /mingw/ ffi_lib File.join($execution_directory, 'ocr/face/Face.dll') ffi_convention :stdcall attach_function :detect_faces, [:pointer, :pointer, :int], :int end end class FaceRecognition extend RCS::Tracer class << self def have_face_recognition_capabilities? File.exist?('ocr/face/haarcascades') end def detect(input_file) return {} unless have_face_recognition_capabilities? if RbConfig::CONFIG['host_os'] =~ /mingw/ found = ffi_detect(input_file) else found = opencv_detect(input_file) end trace :info, "Face detected in #{input_file}" if found {face: found} end def ffi_detect(input_file) face = FACE.detect_faces(input_file, "ocr/face/haarcascades/haarcascade_frontalface_default.xml", 0) trace :error, "Cannot load xml haar file" if face == -1 trace :error, "Cannot load image file" if face == -2 return (face > 0) end def opencv_detect(input_file) image = CvMat.load(input_file) found = [] Dir['ocr/face/haarcascades/*'].each_with_index do |xml, index| found[index] = false CvHaarClassifierCascade::load(xml).detect_objects(image, {scale_factor: 1.1, min_neighbor: 3}).each do |region| trace :debug, "Face detected in #{input_file} by #{File.basename(xml)} [#{region.top_left}, #{region.bottom_right}]" found[index] = true end end # return the element with most occurrences return found.group_by { |n| n }.values.max_by(&:size).first rescue Exception =>e trace :error, "Cannot process image: #{e.message}" return false end end end end #DB:: end #RCS:: .