Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Libpuzzle Mengindeks jutaan gambar?

Jadi, mari kita lihat contoh yang mereka berikan dan coba kembangkan.

Mari kita asumsikan Anda memiliki tabel yang menyimpan informasi yang berkaitan dengan setiap gambar (jalur, nama, deskripsi, dll). Dalam tabel itu, Anda akan menyertakan bidang untuk tanda tangan terkompresi, dihitung dan disimpan saat Anda pertama kali mengisi database. Mari kita definisikan tabel itu sebagai berikut:

CREATE TABLE images (
    image_id INTEGER NOT NULL PRIMARY KEY,
    name TEXT,
    description TEXT,
    file_path TEXT NOT NULL,
    url_path TEXT NOT NULL,
    signature TEXT NOT NULL
);

Saat pertama kali menghitung tanda tangan, Anda juga akan menghitung sejumlah kata dari tanda tangan:

// this will be run once for each image:
$cvec = puzzle_fill_cvec_from_file('img1.jpg');
$words = array();
$wordlen = 10; // this is $k from the example
$wordcnt = 100; // this is $n from the example
for ($i=0; $i<min($wordcnt, strlen($cvec)-$wordlen+1); $i++) {
    $words[] = substr($cvec, $i, $wordlen);
}

Sekarang Anda dapat memasukkan kata-kata tersebut ke dalam tabel, yang didefinisikan sebagai berikut:

CREATE TABLE img_sig_words (
    image_id INTEGER NOT NULL,
    sig_word TEXT NOT NULL,
    FOREIGN KEY (image_id) REFERENCES images (image_id),
    INDEX (image_id, sig_word)
);

Sekarang Anda memasukkan ke dalam tabel itu, dengan menambahkan indeks posisi tempat kata itu ditemukan, sehingga Anda tahu kapan sebuah kata cocok dengannya di tempat yang sama di tanda tangan:

// the signature, along with all other data, has already been inserted into the images
// table, and $image_id has been populated with the resulting primary key
foreach ($words as $index => $word) {
    $sig_word = $index.'__'.$word;
    $dbobj->query("INSERT INTO img_sig_words (image_id, sig_word) VALUES ($image_id,
        '$sig_word')"); // figure a suitably defined db abstraction layer...
}

Dengan demikian, data Anda diinisialisasi, Anda dapat mengambil gambar dengan kata-kata yang cocok dengan relatif mudah:

// $image_id is set to the base image that you are trying to find matches to
$dbobj->query("SELECT i.*, COUNT(isw.sig_word) as strength FROM images i JOIN img_sig_words
    isw ON i.image_id = isw.image_id JOIN img_sig_words isw_search ON isw.sig_word =
    isw_search.sig_word AND isw.image_id != isw_search.image_id WHERE
    isw_search.image_id = $image_id GROUP BY i.image_id, i.name, i.description,
    i.file_path, i.url_path, i.signature ORDER BY strength DESC");

Anda dapat meningkatkan kueri dengan menambahkan HAVING klausa yang membutuhkan strength minimum , sehingga semakin mengurangi set pencocokan Anda.

Saya tidak menjamin bahwa ini adalah penyiapan yang paling efisien, tetapi seharusnya berfungsi secara kasar untuk mencapai apa yang Anda cari.

Pada dasarnya, memisahkan dan menyimpan kata dengan cara ini memungkinkan Anda melakukan pemeriksaan jarak jauh tanpa harus menjalankan fungsi khusus pada tanda tangan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Praktik terbaik untuk bendera bit di PHP

  2. Tidak ada hasil kueri untuk model [App\Products] Laravel

  3. Bagaimana cara mengubah jenis mesin penyimpanan di MySQL?

  4. Mengapa saya tidak menggunakan fungsi mysql_* di PHP?

  5. Integer panjang ditransformasikan ketika dimasukkan ke dalam kolom yang lebih pendek, tidak terpotong. Mengapa? Apa rumusnya?