ในที่สุดฉันก็กลับมาที่ปัญหาและทำให้มันใช้งานได้
ปัญหาคือฉันมีค่า null บางส่วนในฟิลด์ ORDImage...
ฉันพบข้อผิดพลาดโดยพยายามจัดเก็บวัตถุ StillImage ลงในตาราง PHOTOS ของฉันโดยตรง :
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
ไว้ที่ 10 แม้ว่าจะแทนที่ p.phot_source2
ด้วย si_mkstillimage1(p.phot_source.source.localdata)
(ซึ่งเป็นสาเหตุของปัญหา) แต่มันล้มเหลวเมื่อลบข้อจำกัด phot_id
ในที่สุดฉันก็เข้าใจว่าฉันมีค่า null ในคอลัมน์ phot_source
(ORDImage) ที่อาจทำให้เกิดปัญหาได้
และการเรียก SI_StillImage()
Constructor ด้วยพารามิเตอร์ 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 นาที) สำหรับรูปภาพ 5,000 รูป) . ดังนั้นฉันจึงพยายามจัดเก็บคุณสมบัติรูปภาพลงในตารางโดยตรง:
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 ภาพ
ฉันรู้ว่ามันยังช้ามาก แต่ฉันไม่สามารถหาวิธีอื่นในการปรับปรุงประสิทธิภาพได้... ใครมีไอเดียก็อย่าลังเลที่จะแบ่งปัน
person
Yann39
schedule
27.07.2012