sql >> データベース >  >> RDS >> Oracle

SQL / MM静止画像を使用して、BLOB画像をORDImageとして保存されている画像と比較します

    私はついに問題に戻り、それを機能させることができました。

    問題は、単に nullがあったことです。 ORDImageの値 フィールド...

    StillImageを保存しようとしてエラーを見つけました 私の写真に直接反対する テーブル:

    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;
    

    次に、次の最小限の例を実装します :

    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;
    / 
    

    phot_idを制限すると、正常に機能していました。 p.phot_source2を置き換えても10になります si_mkstillimage1(p.phot_source.source.localdata)を使用 (問題を引き起こしていた)。しかし、phot_idを削除すると失敗しました 制限。それで、私はついに私がいくつかの nullを持っていることを理解しました phot_sourceの値 列( ORDImage )問題を引き起こす可能性があります。

    そして実際にSI_StillImage()を呼び出す nullのコンストラクター パラメータにより、次のエラーメッセージが表示されます:

    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
    

    nullをすべて削除しました phot_sourceからの値 列とすべてが正常に動作しています:)

    さらに進むには:

    これの欠点は、テーブルに保存されているすべての画像との比較に非常に長い時間がかかることです( 1155秒(約20分) 5000の場合 写真)。だから私は画像の特徴をテーブルに直接保存しようとしました:

    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
    

    そして、次のように比較します:

    -- 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;
    

    ただし、=を使用して画像の特徴を直接比較することはできないようであるため、次のエラーが発生します。 演算子:

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

    画像の特徴を数値として保存するのが解決策だと思いましたが、ドキュメント 画像フィーチャから対応する数値を取得する方法が見つかりませんでした。

    幸い、SI_score 画像の特徴ごとに関数が用意されているので、以下を使用して画像を比較できます:

    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;
    /
    

    1155秒(約20分)から時間を短縮しました 〜 226秒(3分未満) 5000の場合 画像。

    まだ非常に遅いのはわかっていますが、パフォーマンスを向上させる別の方法を見つけることができません...誰かがアイデアを持っている場合は、遠慮なく共有してください。



    1. プリペアドステートメントのパラメータとしてテーブル名を渡す

    2. phpを介してcsvセルにキャリッジリターンを作成する

    3. 逆SQLSELECT-日付範囲の間にコールドコールを行わなかったスタッフを検索します

    4. テーブルに*を表示する