Пример #1
0
Файл: Art.php Проект: 4otaku/api
 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);
     }
 }
Пример #2
0
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;
}
Пример #3
0
 /**
  * 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;
 }
Пример #4
0
	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);
			}
		}
	}