Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Bandingkan gambar BLOB dengan gambar yang disimpan sebagai ORDImage menggunakan SQL/MM Still Image

Saya akhirnya kembali ke masalah, dan membuatnya bekerja.

Masalahnya adalah saya memiliki beberapa null nilai di ORDImage lapangan...

Saya menemukan kesalahan saya dengan mencoba menyimpan StillImage objek langsung ke FOTO my saya tabel :

alter table PHOTOS add phot_source2 SI_Stillimage;
update photos p set p.phot_source2 = si_stillimage(p.phot_source.source.localData) where p.phot_id < 10;
 

dan kemudian menerapkan contoh minimal berikut ini :

DECLARE
    l_img_obj   si_stillimage;
    l_avgcolor  si_averagecolor;
    l_colorhist si_colorhistogram;
    l_poscolor  si_positionalcolor;
    l_texture   si_texture;
    l_featurelist   si_featurelist;
    l_blob      BLOB;
    l_exist     INTEGER;
BEGIN
    -- get the blob from the ordimage
    SELECT p.phot_source.source.localdata
    INTO l_blob FROM photos p
    WHERE phot_id = 2;
    -- build the stillimage object from the blob
    l_img_obj := NEW si_stillimage(l_blob);
    -- get image features and build the featureList object
    l_avgcolor    := NEW si_averagecolor(l_img_obj);
    l_colorhist   := NEW si_colorhistogram(l_img_obj);
    l_poscolor    := NEW si_positionalcolor(l_img_obj);
    l_texture     := NEW si_texture(l_img_obj);
    l_featurelist := NEW si_featurelist(l_avgcolor, 1, l_colorhist, 1, l_poscolor, 1, l_texture, 1);
    -- check if a similar image is found in the table
    SELECT 1
    INTO l_exist
    FROM photos p
    WHERE si_scorebyftrlist(l_featurelist, p.phot_source2) = 0
    AND phot_id < 10
    AND rownum = 1;
    -- show message if at least one similar photo has been found
    IF (l_exist = 1) THEN       
        dbms_output.put_line('A similar photo has been found');
    END IF;
END;
/ 
 

Itu berfungsi dengan baik saat membatasi phot_id hingga 10, bahkan dengan mengganti p.phot_source2 dengan si_mkstillimage1(p.phot_source.source.localdata) (yang menyebabkan masalah). Tapi gagal saat menghapus phot_id larangan. Jadi saya akhirnya mengerti bahwa saya memiliki beberapa null nilai dalam phot_source kolom (ORDImage ) yang dapat menyebabkan masalah.

Dan memang memanggil SI_StillImage() konstruktor dengan null parameter mengarah ke pesan kesalahan berikut:

ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "ORDSYS.SI_STILLIMAGE", line 27
ORA-06512: at "ORDSYS.SI_MKSTILLIMAGE1", line 6
ORA-06512: at line 24
 

Saya menghapus semua null nilai dari phot_source kolom dan semuanya berfungsi dengan baik sekarang :)

Untuk melangkah lebih jauh:

Kelemahannya adalah dibutuhkan waktu yang sangat lama untuk melakukan perbandingan dengan semua gambar yang tersimpan dalam tabel (1155 detik (sekitar 20 menit) untuk 5000 foto). Jadi saya mencoba untuk menyimpan fitur gambar langsung ke dalam tabel :

alter table photos add ( phot_averagecolor si_averagecolor, phot_colorhistogram si_colorhistogram, phot_positionalcolor si_positionalcolor, phot_texture si_texture ) update photos p set p.phot_averagecolor = si_averagecolor(si_stillimage(p.phot_source.source.localData)), p.phot_colorhistogram = si_colorhistogram(si_stillimage(p.phot_source.source.localData)), p.phot_positionalcolor = si_positionalcolor(si_stillimage(p.phot_source.source.localData)), p.phot_texture = si_texture(si_stillimage(p.phot_source.source.localData)) where p.phot_id < 10

Kemudian lakukan perbandingan seperti ini :

-- get the blob from the ordimage
SELECT p.phot_source.source.localdata
INTO l_blob FROM photos p
WHERE phot_id = 2;
-- build the stillimage object from the blob
l_img_obj := NEW si_stillimage(l_blob);
-- get image features and build the featureList object
l_avgcolor    := si_averagecolor(l_img_obj);
l_colorhist   := si_colorhistogram(l_img_obj);
l_poscolor    := si_positionalcolor(l_img_obj);
l_texture     := si_texture(l_img_obj);
l_featurelist := NEW si_featurelist(l_avgcolor, 1, l_colorhist, 1, l_poscolor, 1, l_texture, 1);
-- check if a similar image is found in the table
SELECT 1
INTO l_exist
FROM photos p
WHERE p.phot_averagecolor = l_avgcolor
AND p.phot_colorhistogram = l_colorhist
AND p.phot_positionalcolor = l_poscolor
AND p.phot_texture = l_texture
AND p.phot_id < 10
AND rownum = 1;
 

Tetapi ini memberikan kesalahan berikut karena tampaknya tidak mungkin untuk membandingkan fitur gambar secara langsung menggunakan = operator :

ORA-22901: cannot compare VARRAY or LOB attributes of an object type
ORA-06512: at line 24
 

Saya pikir solusinya adalah menyimpan fitur gambar sebagai nilai numerik, tetapi saya membaca seluruh dokumentasi dan saya belum menemukan cara untuk mendapatkan nilai numerik yang sesuai dari fitur gambar.

Untungnya, SI_score fungsi disediakan untuk setiap fitur gambar, jadi kita dapat menggunakan yang berikut untuk membandingkan gambar:

DECLARE
    l_img_obj   si_stillimage;
    l_blob      BLOB;
    l_exist     INTEGER;
BEGIN
    -- get the blob from the ordimage
    SELECT p.phot_source.source.localdata
    INTO l_blob FROM photos p
    WHERE phot_id = 2;
    -- build the stillimage object from the blob
    l_img_obj := NEW si_stillimage(l_blob);
    -- check if a similar image is found in the table
    SELECT 1
    INTO l_exist
    FROM photos p
    WHERE p.phot_averagecolor.SI_Score(l_img_obj) = 0
    AND p.phot_colorhistogram.SI_Score(l_img_obj) = 0
    AND p.phot_positionalcolor.SI_Score(l_img_obj) = 0
    AND p.phot_texture.SI_Score(l_img_obj) = 0
    AND rownum = 1;
    -- show message
    dbms_output.put_line(l_count || ' similar photo(s) found');
END;
/
 

Saya mengurangi waktu dari 1155 detik (sekitar 20 menit) hingga 226 detik (kurang dari 3 menit) untuk 5000 gambar.

Saya tahu, ini masih sangat lambat, tetapi saya tidak dapat menemukan cara lain untuk meningkatkan kinerja..., jika ada yang punya ide jangan ragu untuk berbagi.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ORA-04091:tabel bermutasi, pemicu/fungsi mungkin tidak melihatnya kesalahan selama eksekusi pemicu Oracle

  2. ORA-21700:objek tidak ada atau ditandai untuk dihapus untuk Associative Array sebagai parameter input yang dipanggil dari ODP.NET

  3. Bagaimana saya bisa menjatuhkan batasan bukan nol di Oracle ketika saya tidak tahu nama batasannya?

  4. Bisakah saya membuat Kunci Asing di seluruh Basis Data?

  5. java.lang.ArrayIndexOutOfBoundsException di oracle.jdbc.driver.T4CTTIrxd.readBitVector(T4CTTIrxd.java:135)