多分辨率图像的快速查询
原始論文:http://research.microsoft.com/apps/pubs/?id=69465
原始項目介紹:http://grail.cs.washington.edu/projects/query/
基于該成果的一些實現:
http://www.visgraf.impa.br/Courses/ipcg-query-1998/(課程作業,沒有找到源碼)
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.107.2241&rep=rep1&type=pdf (源碼鏈接失效,python)
http://eikon.recursion.org/ (有源碼,實現較為復雜,且運行出錯,沒有仔細研究出錯原因,java)
基于該成果的擴展實現:
Fast Nonparametric Machine Learning Algorithms for High-dimensional Massive Data and Applications(Ting liu)(重點是knn)
?
目的:由掃描的低分辨率圖像或者手繪的粗糙圖像搜索到相應的高分辨率圖像
?
算法描述:
包括預處理與搜索兩部分,預處理是對圖像信息的提取,搜索是計算匹配程度
預處理:
1、調整圖片為預定義的大小(64×64)
調整圖片意味著分辨率的下降,也意味著處理數據的減少,我采用的參數是64×64,或許128×128效果更好。
以下兩種方法我都試了,差別不大,不過鑒于第一種是eikon用過的,最后還是采用它了
?public static BufferedImage scale(BufferedImage image)
??? {
??? double xscale;
??? double yscale;
???
??? xscale = (double)64 / (double)image.getWidth();
??? yscale = (double)64 / (double)image.getHeight();
??? AffineTransformOp op = new
??? ??? AffineTransformOp(AffineTransform.getScaleInstance(xscale, yscale),
??? ??? ??? ????? null);
???
??? return op.filter(image, null);
??? }
?
??? public BufferedImage resize(Image original, int width, int height, ImageObserver observer) {
??????? BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
???????
??????? Graphics2D g2 = bufferedImage.createGraphics();
??????? g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
??????????????? RenderingHints.VALUE_INTERPOLATION_BILINEAR);
??????? g2.drawImage(original, 0, 0, width, height, observer);
???????
??????? return bufferedImage;
??? }
?
?
2、將BGR顏色轉換為YIQ顏色
通過實驗,論文認為YIQ顏色模型效果最好。
YIQ與BGR的轉換:
???? ??? ??? ?? array_YIQ[0][i][j]=(0.299*array_BGR[0][i][j]+0.587*array_BGR[1][i][j]+0.114*array_BGR[2][i][j])/256;
??? ??? ??? ??? array_YIQ[1][i][j]=(0.596*array_BGR[0][i][j]-0.274*array_BGR[1][i][j]-0.322*array_BGR[2][i][j])/256;
??? ??? ??? ??? array_YIQ[2][i][j]=(0.212*array_BGR[0][i][j]-0.523*array_BGR[1][i][j]+0.311*array_BGR[2][i][j])/256;
得到三個矩陣,分別對應Y、I、Q顏色通道
3、進行haar小波分解
依次處理各矩陣,先對每一行分解,再對每一列分解
??? private static double[]? decomposeArray(double[] bs) {
??? ??? int h=bs.length;
??? ??? double t=Math.sqrt(h);
??? ??? final double SQRT_2=Math.sqrt(2);
??? ??? double[] bs_new=new double[h];
??? ??? for(int i=0;i<h;i++)
??? ??? ??? bs[i]=bs[i]/t;
??? ??? while(h>1){
??? ??? ??? h=h/2;
??? ??? ??? for(int i=0;i<h-1;i++){
??? ??? ??? ??? bs_new[i]=(bs[2*i]+bs[2*i+1])/SQRT_2;
??? ??? ??? ??? bs_new[h+i]=(bs[2*i]-bs[2*i+1])/SQRT_2;
??? ??? ??? }
??? ??? }
??? ??? return bs_new;
??? }
4、保留除(0,0)以外的最大的m個系數
對每個顏色矩陣,元素(0,0)為該顏色的平均值。
選擇除(0,0)以外最大的m個元素,其他元素全部置為0。試了兩種方法:1是選擇排序,選m個最大值;2是先全部排好序,再保留前m個值。第二種實現比較容易。
作者建議m=60甚至40,但我的實驗結果看來m=200比較合適(因為我的查詢圖片既不是掃描也不是素描,我想查到相似的多副圖片,不一定是原圖)如果不考慮效率m還可以更大一點,其實圖片數目很少機器配置又不錯的時候,m=2000也可以很快跑完。
5、量化系數為+1/-1
對顏色矩陣進一步處理:
value>0 +1
value<0 -1
6、將圖片添加到6個搜索數組中,每個數組對應一個顏色通道的正/負值,如Y+對應系數為+的Y通道,若圖片Y通道的(8,9)為+1,它將被添加到Y+的元素(8,9)中
信息也不多,用數據庫太麻煩,我將處理過的圖片信息保存為磁盤文件,當查詢時再讀入
?
搜索:
1、獲取查詢圖像
2、通過預處理得到查詢圖像信息
同樣是進行預處理,獲得三個量化過的顏色矩陣
3、根據查詢圖像,計算已存圖像的度量分數(計算公式見論文)
4、按分數由低到高排列,越低越匹配
5、返回前n個結果給用戶
?
結果分析:
這種方法在查找相同但是有些變化的圖片(比如太陽、同一建筑物)時表現理想,但對相似的圖片(如風格相似的不同圖片)基本沒有作用。此外,當背景顏色范圍廣、相差大時,效果也不理想。
轉載于:https://www.cnblogs.com/altya/archive/2010/07/26/1785295.html
總結
以上是生活随笔為你收集整理的多分辨率图像的快速查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经典SQL短小代码收集汇总
- 下一篇: Spring.NET实用技巧3——NHi