图像分类

图片地理标记即图像分类,可以实现多张图片进行特定的标志性物体分类。主要步骤需要对图像提取局部描述算子,一般情况都是使用SIFT特征描述算子。然后通过判断图像是否具有匹配的局部描述算子来定义图像之间的连接,实现图像可视化连接,图的边代表连接。在实现图像连接将会使用pydot工具包,该工具包是功能强大的GraphViz图形库的Python接口。

(一)安装graphviz

首先下载安装graphviz-2.38.msi,再运行命令pip install pydot,最后可在系统路径PATH中添加graphviz的路径:C:\Program Files (x86)\Graphviz2.38\bin。(注意:graphviz安装路径可以随便存。pydot的Node节点添加图片时,图片的路径需要为绝对路径,且分隔符为/ 

下载连接:https://graphviz.gitlab.io/_pages/Download/Download_windows.html

双击graphviz-2.38进行安装。

点next安装成功过后,就要把路径添加到环境变量path里。具体步骤:此电脑-->属性-->高级系统设置-->环境变量-->path,然后新建添加其路径:E:\360Downloads\Graphviz2.38\bin

窗口键+R输入cmd,在出现的命令窗口输入:pip install pydot

完成以上步骤,环境配置就基本成功了。

(二)图片分类实现

具体实现时,要先创建一个sift.py文件,然后把要分类的图片都存在该项目下(注意:所有图片之间像素不要相差太大,最好可以用美图秀秀批处理进行以同一宽度自适应高度生成图片),就可以直接运行一下代码:

# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from numpy import *
import os
import pydot
import siftdef get_imlist(path):return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.jpg')]# pydot需要绝对路径,路径分隔符为/而非\
download_path = "E:/Python37_course/test"
path = "E:/Python37_course/test/"# list of downloaded filenames
imlist = get_imlist(download_path)
nbr_images = len(imlist)# extract features
featlist = [imname[:-3] + 'sift' for imname in imlist]
for i, imname in enumerate(imlist):sift.process_image(imname, featlist[i])matchscores = zeros((nbr_images, nbr_images))for i in range(nbr_images):for j in range(i, nbr_images): #only compute upper triangleprint ('comparing ', imlist[i], imlist[j])l1, d1 = sift.read_features_from_file(featlist[i])l2, d2 = sift.read_features_from_file(featlist[j])matches = sift.match_twosided(d1, d2)nbr_matches = sum(matches>0)print ('number of matches = ', nbr_matches)matchscores[i,j] = nbr_matches
print ("The match scores is: \n", matchscores)# copy values
for i in range(nbr_images):for j in range(i + 1, nbr_images): # no need to copy diagonalmatchscores[j, i] = matchscores[i, j]# 可视化
threshold = 2 # min number of matches needed to craete linkg = pydot.Dot(graph_type='graph') # don't want the default directed graphfor i in range(nbr_images):for j in range(i+1, nbr_images):if matchscores[i,j] > threshold:#图像对中的第一幅图像im = Image.open(imlist[i])im.thumbnail((100,100))filename = path + str(i) + '.png'im.save(filename) #需要一定大小的临时文件g.add_node(pydot.Node(str(i), fontcolor='transparent',shape='rectangle', image=filename))#图像对中的第二幅图像im = Image.open(imlist[j])im.thumbnail((100,100))filename = path + str(j) + '.png'im.save(filename) #需要一定大小的临时文件g.add_node(pydot.Node(str(j), fontcolor='transparent',shape='rectangle', image=filename))g.add_edge(pydot.Edge(str(i), str(j)))
g.write_png('whitehouse.png')

sift.py文件

from PIL import Image
import os
from numpy import *
from pylab import *def process_image(imagename, resultname, params="--edge-thresh 10 --peak-thresh 5"):""" 处理一幅图像,然后将结果保存在文件中"""if imagename[-3:] != 'pgm':#创建一个pgm文件im = Image.open(imagename).convert('L')im.save('tmp.pgm')imagename ='tmp.pgm'cmmd = str("sift "+imagename+" --output="+resultname+" "+params)os.system(cmmd)print ('processed', imagename, 'to', resultname)def read_features_from_file(filename):"""读取特征属性值,然后将其以矩阵的形式返回"""f = loadtxt(filename)return f[:,:4], f[:,4:] #特征位置,描述子def write_featrues_to_file(filename, locs, desc):"""将特征位置和描述子保存到文件中"""savetxt(filename, hstack((locs,desc)))def plot_features(im, locs, circle=False):"""显示带有特征的图像输入:im(数组图像),locs(每个特征的行、列、尺度和朝向)"""def draw_circle(c,r):t = arange(0,1.01,.01)*2*pix = r*cos(t) + c[0]y = r*sin(t) + c[1]plot(x, y, 'b', linewidth=2)imshow(im)if circle:for p in locs:draw_circle(p[:2], p[2])else: plot(locs[:,0], locs[:,1], 'ob')axis('off')def match(desc1, desc2):"""对于第一幅图像中的每个描述子,选取其在第二幅图像中的匹配输入:desc1(第一幅图像中的描述子),desc2(第二幅图像中的描述子)"""desc1 = array([d/linalg.norm(d) for d in desc1])desc2 = array([d/linalg.norm(d) for d in desc2])dist_ratio = 0.6desc1_size = desc1.shapematchscores = zeros((desc1_size[0],1),'int')desc2t = desc2.T #预先计算矩阵转置for i in range(desc1_size[0]):dotprods = dot(desc1[i,:],desc2t) #向量点乘dotprods = 0.9999*dotprods# 反余弦和反排序,返回第二幅图像中特征的索引indx = argsort(arccos(dotprods))#检查最近邻的角度是否小于dist_ratio乘以第二近邻的角度if arccos(dotprods)[indx[0]] < dist_ratio * arccos(dotprods)[indx[1]]:matchscores[i] = int(indx[0])return matchscores def match_twosided(desc1, desc2):"""双向对称版本的match()"""matches_12 = match(desc1, desc2)matches_21 = match(desc2, desc1)ndx_12 = matches_12.nonzero()[0]# 去除不对称的匹配for n in ndx_12:if matches_21[int(matches_12[n])] != n:matches_12[n] = 0return matches_12def appendimages(im1, im2):"""返回将两幅图像并排拼接成的一幅新图像"""#选取具有最少行数的图像,然后填充足够的空行rows1 = im1.shape[0]rows2 = im2.shape[0]if rows1 < rows2:im1 = concatenate((im1, zeros((rows2-rows1,im1.shape[1]))),axis=0)elif rows1 >rows2:im2 = concatenate((im2, zeros((rows1-rows2,im2.shape[1]))),axis=0)return concatenate((im1,im2), axis=1)def plot_matches(im1,im2,locs1,locs2,matchscores,show_below=True):""" 显示一幅带有连接匹配之间连线的图片输入:im1, im2(数组图像), locs1,locs2(特征位置),matchscores(match()的输出),show_below(如果图像应该显示在匹配的下方)"""im3=appendimages(im1,im2)if show_below:im3=vstack((im3,im3))imshow(im3),title('SIFT特征匹配')cols1 = im1.shape[1]for i in range(len(matchscores)):if matchscores[i]>0:plot([locs1[i,0],locs2[matchscores[i,0],0]+cols1], [locs1[i,1],locs2[matchscores[i,0],1]],'c')axis('off')

运行代码:

如果出现:

因为我是一次就运行成功,没有遇到错误。(1)出现没有生成PNG图片错误,一般都是路径配置错误;所以路径加入path环境变量的时候一定要加到:系统变量的path里。

提示:在sift特征方法里我用的vlfeat是0.9.20版本,(2)如果出现IndexError :too many indices for array错误,可以尝试换vlfeat是0.9.17版本.

(3)如果还出现sift描述算子的.sift找不到错误,可以查看这篇相关博文连接:https://blog.csdn.net/weixin_43837871/article/details/88604483

(三)图像分类结果展现

下图是项目文件夹:

计算机视觉——图像地理位置标记相关推荐

  1. Python计算机视觉——图像到图像的映射

    Python计算机视觉--图像到图像的映射 文章目录 Python计算机视觉--图像到图像的映射 写在前面 1 单应性变换 1.1 直接线性变换算法 1.2 仿射变换 2 图像扭曲 2.1 图像中的图 ...

  2. Dataset:数据集集合(CV方向数据集)-常见的计算机视觉图像数据集大集合包括表面缺陷检测数据集(持续更新)

    Dataset:数据集集合(CV方向数据集)-常见的计算机视觉图像数据集大集合包括表面缺陷检测数据集(建议收藏,持续更新) 目录 CV常用数据集平台集合 Mendeley Data CAISA-Web ...

  3. Dataset之CV:人工智能领域数据集集合(计算机视觉CV方向数据集)之常见的计算机视觉图像数据集大集合(包括表面缺陷检测数据集,持续更新)

    Dataset之CV:人工智能领域数据集集合(计算机视觉CV方向数据集)之常见的计算机视觉图像数据集大集合(包括表面缺陷检测数据集,持续更新) 目录 CV常用数据集平台集合 Mendeley Data ...

  4. CV:计算机视觉技术之图像基础知识(二)—以python的skimage和numpy库来了解计算机视觉图像基础(图像存储原理-模糊核-锐化核-边缘检测核,进阶卷积神经网络(CNN)的必备基础)

    CV:计算机视觉技术之图像基础知识(二)-以python的skimage和numpy库来了解计算机视觉图像基础(图像存储原理-模糊核-锐化核-边缘检测核,进阶卷积神经网络(CNN)的必备基础) 目录 ...

  5. CV:计算机视觉技术之图像基础知识—以python的cv2库来了解计算机视觉图像基础

    CV:计算机视觉技术之图像基础知识-以python的cv2库来了解计算机视觉图像基础 目录 一.图像中的傅里叶变换 1.时域和频域 2.傅里叶变换 3.图像中的傅里叶变换

  6. CV:计算机视觉技术之图像基础知识(一)—以python的cv2库来了解计算机视觉图像基础(傅里叶变换-频域-时域/各种滤波器-线性-非线性-均值-中值-高斯-双边)

    CV:计算机视觉技术之图像基础知识(一)-以python的cv2库来了解计算机视觉图像基础(傅里叶变换-频域-时域/各种滤波器-线性-非线性-均值-中值-高斯-双边) 目录 一.图像中的傅里叶变换 1 ...

  7. ITK:为图像中标记区域的边界上色

    ITK:为图像中标记区域的边界上色 内容提要 输出结果 C++实现代码 内容提要 为图像中标记区域的边界上色. 输出结果 C++实现代码 #include "itkBinaryImageTo ...

  8. 图像连通域标记算法研究

    搬以前写的博客[2014-03-01 08:09] 图像连通域标记算法研究 ConnectedComponent Labeling 最近在研究一篇复杂下背景文字检测的论文. "Detecti ...

  9. 计算机视觉--图像的拼接融合

    计算机视觉--图像的拼接融合 一.全景图像拼接原理介绍 1.1 背景介绍 1.2 基本原理 1.3 图像拼接整体流程 二.全景图像拼接实验 2.1 代码实现 2.2 不同场景的实验结果与分析 2.2. ...

最新文章

  1. javascript函数值的重写
  2. php 实现 pacs 系统,影像管理系统(PACS)
  3. eclipse jdbc mysql下载_在eclipse里jdbc连接mysql 怎么安装
  4. OpenCV均值移位(Meanshift)和Camshift算法
  5. leetcode:203. 移除链表元素(两种方法)
  6. 净资产滚动率_净资产的结构
  7. 【Elasticsearch】 es 索引 内置 字段 _source
  8. import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder; 报错的解决方法
  9. 语言编出的程序怎么实装_程序员小白:编程语言到底该怎么选?
  10. C# 使用iTextSharp中间件打印PDF
  11. Power Platform 介绍
  12. 笔记_python库jpype安装和使用,及如何打包java程序供Python调用
  13. Selenium中的EC模块
  14. java把小写变大写_用java实现人民币小写变大写的方法
  15. Chrono-Chrome下载管理插件
  16. centos7安装拼音输入法
  17. 外卖匹配系统_快餐外卖系统的需求分析
  18. 各种LED显示模组的技术分析(1)扫描接口
  19. 微信公众号查看粉丝信息接口
  20. linux命令记忆方法,Linux命令快速巧记法

热门文章

  1. vue遇到ie兼容问题如何处理_详解vue 兼容IE报错解决方案
  2. python求三个数平均值_Python操作Excel教程-average函数求平均值
  3. 电脑快捷键大全!职场必备!
  4. 北京求职日记 java 第一天
  5. 梦幻西游 python_如何评价现在的《梦幻西游》电脑版?
  6. html5视频播放器带ID跑马灯效果(视频防录屏)
  7. 阿德勒心理学——关于《被讨厌的勇气》一书的思考
  8. 多标签算法:MASP 的理论与Python代码分析
  9. 微信 html 选不上文件,微信内网页某些安卓手机不能上传图片文件的问题
  10. 管理方面的书籍推荐,这些书值得一看