protected function track_similar() { if (!function_exists('puzzle_fill_cvec_from_file') || !function_exists('puzzle_vector_normalized_distance') || !function_exists('puzzle_compress_cvec') || !function_exists('puzzle_uncompress_cvec')) { return; } $unparsed = $this->db->limit(100)->get_vector('art', array('id', 'md5', 'ext'), 'vector = ""'); foreach ($unparsed as $id => $image) { $file = IMAGES . SL . 'art' . SL . $image['md5'] . '.' . $image['ext']; $vector = puzzle_fill_cvec_from_file($file); $vector = base64_encode(puzzle_compress_cvec($vector)); $this->db->update('art', array('similar_tested' => 0, 'vector' => $vector), $id); } $all = $this->db->get_vector('art', array('id', 'vector'), 'vector != ""'); $arts = $this->db->limit(100)->get_vector('art', array('id', 'vector'), 'vector != "" and similar_tested = 0'); foreach ($all as $id => $vector) { $all[$id] = puzzle_uncompress_cvec(base64_decode($vector)); } foreach ($arts as $id => $vector) { $vector = puzzle_uncompress_cvec(base64_decode($vector)); foreach ($all as $compare_id => $compare_vector) { if ($id != $compare_id && puzzle_vector_normalized_distance($vector, $compare_vector) < 0.3) { $id_first = min($id, $compare_id); $id_second = max($id, $compare_id); $this->db->insert('art_similar', array('id_first' => $id_first, 'id_second' => $id_second)); } } $this->db->update('art', array('similar_tested' => 1), $id); } }
function find_similar_pictures($md5, $cvec, $threshold = PUZZLE_CVEC_SIMILARITY_THRESHOLD) { $compressed_cvec = puzzle_compress_cvec($cvec); $words = split_into_words($cvec); $dbh = new PDO(DB_DSN); $dbh->beginTransaction(); $sql = 'SELECT DISTINCT(signature_id) AS signature_id FROM words ' . 'WHERE pos_and_word IN ('; $coma = FALSE; foreach ($words as $u => $word) { if ($coma === TRUE) { $sql .= ','; } $sql .= $dbh->quote(chr($u) . puzzle_compress_cvec($word)); $coma = TRUE; } $sql .= ')'; $res_words = $dbh->query($sql); $scores = array(); $st = $dbh->prepare('SELECT compressed_signature, picture_id ' . 'FROM signatures WHERE id = :id'); while (($signature_id = $res_words->fetchColumn()) !== FALSE) { $st->execute(array(':id' => $signature_id)); $row = $st->fetch(); $found_compressed_signature = $row['compressed_signature']; $picture_id = $row['picture_id']; $found_cvec = puzzle_uncompress_cvec($found_compressed_signature); $distance = puzzle_vector_normalized_distance($cvec, $found_cvec); if ($distance < $threshold && $distance > 0.0) { $scores[$picture_id] = $distance; } } $sql = 'SELECT url FROM sentpictures WHERE picture_id IN ('; $coma = FALSE; foreach ($scores as $picture_id => $score) { if ($coma === TRUE) { $sql .= ','; } $sql .= $dbh->quote($picture_id); $coma = TRUE; } $sql .= ')'; $urls = array(); if (!empty($scores)) { $res_urls = $dbh->query($sql); while (($url = $res_urls->fetchColumn()) !== FALSE) { array_push($urls, $url); } } $dbh->commit(); return $urls; }
/** * Get possible matches from sql index * * @param binary $signature Image signature * @param integer $from Offset * @param integer $count Limit * * @return binary vector signature * @throws Ansel_Exception */ public function getSignatureMatches($signature, $face_id = 0, $from = 0, $count = 0) { $word_len = $GLOBALS['conf']['faces']['search']; $str_len = strlen($signature); $c = $str_len - $word_len; $indexes = array(); for ($i = 0; $i <= $c; $i++) { $sig = new Horde_Db_Value_Binary(substr($signature, $i, $word_len)); $indexes[] = '(index_position = ' . $i . ' AND index_part = ' . $sig->quote($GLOBALS['ansel_db']) . ')'; } $sql = 'SELECT i.face_id, f.face_name, ' . 'f.image_id, f.gallery_id, f.face_signature ' . 'FROM ansel_faces_index i, ansel_faces f ' . 'WHERE f.face_id = i.face_id'; if ($face_id) { $sql .= ' AND i.face_id <> ' . (int) $face_id; } if ($indexes) { $sql .= ' AND (' . implode(' OR ', $indexes) . ')'; } $sql .= ' GROUP BY i.face_id, f.face_name, f.image_id, f.gallery_id, ' . 'f.face_signature HAVING count(i.face_id) > 0 ' . 'ORDER BY count(i.face_id) DESC'; $sql = $GLOBALS['ansel_db']->addLimitOffset($sql, array('limit' => $count, 'offset' => $from)); try { $faces = $GLOBALS['ansel_db']->selectAll($sql); } catch (Horde_Db_Exception $e) { throw new Ansel_Exception($e); } if (empty($faces)) { return array(); } foreach ($faces as &$face) { $face['similarity'] = puzzle_vector_normalized_distance($signature, puzzle_uncompress_cvec($face['face_signature'])); } uasort($faces, array($this, '_getSignatureMatches')); return $faces; }
function is_dublicates() { $arts = explode(',', query::$get['data']); if ( count($arts) < 2 || !function_exists('puzzle_fill_cvec_from_file') || !function_exists('puzzle_vector_normalized_distance') ) { return false; } foreach ($arts as $key => $art) { $file = ROOT_DIR.SL.'images'.SL.'booru'.SL.'thumbs'.SL.'large_'.$art.'.jpg'; $arts[$key] = puzzle_fill_cvec_from_file($file); } foreach ($arts as $key => $art) { foreach ($arts as $key2 => $compare_art) { if ( $key != $key2 && puzzle_vector_normalized_distance($art, $compare_zart) > 0.3 ) { return false; } } } return count($arts); }
function track_similar_pictures() { if ( !function_exists('puzzle_fill_cvec_from_file') || !function_exists('puzzle_vector_normalized_distance') || !function_exists('puzzle_compress_cvec') || !function_exists('puzzle_uncompress_cvec') ) { return; } /* $max = obj::db()->sql('select max(id) from art_similar',2); $arts = obj::db()->sql('select id, thumb from art where id > '.($max ? $max : 0).' and area != "deleted" order by id limit 2000'); foreach ($arts as $art) { $image = ROOT_DIR.SL.'images'.SL.'booru'.SL.'thumbs'.SL.'large_'.$art['thumb'].'.jpg'; $vector = puzzle_fill_cvec_from_file($image); $vector = base64_encode(puzzle_compress_cvec($vector)); obj::db()->insert('art_similar',array($art['id'], $vector, 0, ''),false); } */ $all = obj::db()->sql('select id, vector from art_similar where vector != ""','id'); $arts = obj::db()->sql('select * from art_similar where vector != "" and checked=0 limit 100','id'); if (is_array($all) && is_array($arts)) { foreach ($all as $compare_id => $vector) { $all[$compare_id] = puzzle_uncompress_cvec(base64_decode($vector)); } foreach ($arts as $id => $art) { $art['vector'] = puzzle_uncompress_cvec(base64_decode($art['vector'])); $similar = '|'; $art_area = false; foreach ($all as $compare_id => $vector) { if ( $id != $compare_id && puzzle_vector_normalized_distance($art['vector'], $vector) < 0.3 ) { if (empty($art_area)) { $art_area = Database::get_field('art', 'area', $id); } if ($art_area == 'cg' && Database::get_field('art', 'area', $compare_id) == 'cg') { continue; } $similar .= $compare_id.'|'; } } obj::db()->update('art_similar',array('checked','similar'),array(1,$similar),$id); } } }