このブログには複数の非常に詳細な概要もあり、興味のある友人は次のリンクに移動できます。
畳み込みニューラル ネットワーク:畳み込みニューラル ネットワークの超詳細な入門
物体検出:物体検出の超詳細な紹介
セマンティック セグメンテーション:セマンティック セグメンテーションの超詳細な紹介
NMS: NMS 全体とそのバリエーションを理解して確認できるようにします。
データ拡張:コンピューター ビジョンにおけるデータ拡張を理解するための記事
損失関数:分類検出セグメンテーションにおける損失関数と評価指標
トランスフォーマー:ビジュアルトランスフォーマーに関する調査
機械学習実践シリーズ:ディシジョンツリー
YOLO シリーズ:v1、v2、v3、v4、scaled-v4、v5、v6、v7、yolof、yolox、yolos、yolop
1 基本的な画像操作と処理
1.1 PIL: Python画像処理ライブラリ
PIL (Python Imaging Library、画像処理ライブラリ) は、一般的な画像処理関数に加えて、多数の便利な基本的な画像操作を提供します。PIL ライブラリは Anaconda ライブラリに統合されました。シンプルで便利でよく使用されるライブラリが統合されている Anaconda を使用することをお勧めします。
- 画像で読み取る:
from PIL import Image
from pylab import *
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
figure()
pil_im = Image.open('E:\python\Python Computer Vision\Image data\empire.jpg')
gray()
subplot(121)
title(u'原图',fontproperties=font)
axis('off')
imshow(pil_im)
pil_im = Image.open('E:\python\Python Computer Vision\Image data\empire.jpg').convert('L')
subplot(122)
title(u'灰度图',fontproperties=font)
axis('off')
imshow(pil_im)
show()
1.1.1 画像フォーマット変換 -save()
機能
from PCV.tools.imtools import get_imlist #导入原书的PCV模块
from PIL import Image
import os
import pickle
filelist = get_imlist('E:/python/Python Computer Vision/test jpg/') #获取convert_images_format_test文件夹下的图片文件名(包括后缀名)
imlist = open('E:/python/Python Computer Vision/test jpg/imlist.txt','wb+')
#将获取的图片文件列表保存到imlist.txt中
pickle.dump(filelist,imlist) #序列化
imlist.close()
for infile in filelist:
outfile = os.path.splitext(infile)[0] + ".png" #分离文件名与扩展名
if infile != outfile:
try:
Image.open(infile).save(outfile)
except IOError:
print ("cannot convert", infile)
このうち、test jpg フォルダーは、テスト済みの **.jpg 画像を保存するために作成者によって作成されたフォルダーであり、取得した画像ファイル名を保存し、すべての画像を .png 形式に変換するためのコードがソース コード証明書に追加されます。プログラムを実行した後の結果は次のとおりです。
<img src="https://img-blog.csdn.net/20180306084511595?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhb3lhbmd3bQ==/font/5a6L5L2T/fontsize/400/fill/I0 JBQkFCMA== /dissolve/70"width="47.5%",alt=""/>
PIL の open() 関数を使用して PIL 画像オブジェクトを作成し、sace() メソッドを使用して以下を指定したファイル名でフォルダーに保存します。上記のプロセスではサフィックスが .png に変更されますが、ファイルは名前は変更されません。
1.1.2 サムネイルの作成
PIL を使用すると、サムネイルを簡単に作成し、サムネイルのサイズを設定し、タプルに保存し、thumnail()
サムネイルを生成するメソッドを呼び出すことができます。サムネイルを作成するコードは以下のとおりです。
たとえば、最長辺が 128 ピクセルのサムネイルを作成するには、次を使用できます。
pil_im.thumbnail((128,128))
####1.1.3 画像領域のコピーと貼り付け
Crop() メソッドを呼び出して、画像から領域をコピーします。領域をコピーした後、その領域に対して回転やその他の変換を実行できます。
box=(100,100,400,400)
region=pil_im.crop(box)
対象領域を4倍で指定し、座標は(左、上、右、下) PILで指定した座標系の左上隅の座標は(0, 0)となり、回転して置くことができますpast() で戻ります。具体的な実装は次のとおりです。
region=region.transpose(Image.ROTATE_180)
pil_im.paste(region,box)
1.1.4 サイズ変更と回転
- サイズ変更:
resize()
メソッドを使用します。パラメータは新しい画像のサイズを指定するタプルです。
out=pil_im.resize((128,128))
- 回転:
rotate()
反時計回りに角度を表す方法を使用します。
out=pil_im.rotate(45)
上記の操作のコードは次のとおりです。
from PIL import Image
from pylab import *
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
figure()
# 显示原图
pil_im = Image.open('E:/python/Python Computer Vision/Image data/empire.jpg')
print(pil_im.mode, pil_im.size, pil_im.format)
subplot(231)
title(u'原图', fontproperties=font)
axis('off')
imshow(pil_im)
# 显示灰度图
pil_im = Image.open('E:/python/Python Computer Vision/Image data/empire.jpg').convert('L')
gray()
subplot(232)
title(u'灰度图', fontproperties=font)
axis('off')
imshow(pil_im)
# 复制并粘贴区域
pil_im = Image.open('E:/python/Python Computer Vision/Image data/empire.jpg')
box = (100, 100, 400, 400)
region = pil_im.crop(box)
region = region.transpose(Image.ROTATE_180)
pil_im.paste(region, box)
subplot(233)
title(u'复制粘贴区域', fontproperties=font)
axis('off')
imshow(pil_im)
# 缩略图
pil_im = Image.open('E:/python/Python Computer Vision/Image data/empire.jpg')
size = 128, 128
pil_im.thumbnail(size)
print(pil_im.size)
subplot(234)
title(u'缩略图', fontproperties=font)
axis('off')
imshow(pil_im)
pil_im.save('E:/python/Python Computer Vision/Image data/empire thumbnail.jpg')# 保存缩略图
#调整图像尺寸
pil_im=Image.open('E:/python/Python Computer Vision/Image data/empire thumbnail.jpg')
pil_im=pil_im.resize(size)
print(pil_im.size)
subplot(235)
title(u'调整尺寸后的图像',fontproperties=font)
axis('off')
imshow(pil_im)
#旋转图像45°
pil_im=Image.open('E:/python/Python Computer Vision/Image data/empire thumbnail.jpg')
pil_im=pil_im.rotate(45)
subplot(236)
title(u'旋转45°后的图像',fontproperties=font)
axis('off')
imshow(pil_im)
show()
操作の結果は次のようになります。
1.2 Matplotlib ライブラリ
数学やグラフィックスを扱ったり、画像上に点をプロットしたり、線や曲線を描いたりする場合、Matplotlib は、PIL ライブラリよりも強力な機能を提供する優れたグラフィックス ライブラリです。
1.2.1 点と線の描画、プロット
from PIL import Image
from pylab import *
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
# 读取图像到数组中
im = array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg'))
figure()
# 绘制有坐标轴的
subplot(121)
imshow(im)
x = [100, 100, 400, 400]
y = [200, 500, 200, 500]
# 使用红色星状标记绘制点
plot(x, y, 'r*')
# 绘制连接两个点的线(默认为蓝色)
plot(x[:2], y[:2])
title(u'绘制empire.jpg', fontproperties=font)
# 不显示坐标轴的
subplot(122)
imshow(im)
x = [100, 100, 400, 400]
y = [200, 500, 200, 500]
plot(x, y, 'r*')
plot(x[:2], y[:2])
axis('off')
title(u'绘制empire.jpg', fontproperties=font)
show()
# show()命令首先打开图形用户界面(GUI),然后新建一个窗口,该图形用户界面会循环阻断脚本,然后暂停,
# 直到最后一个图像窗口关闭。每个脚本里,只能调用一次show()命令,通常相似脚本的结尾调用。
表 1-1、1-2、1-3 に示すように、描画時には多くのオプションの色とスタイルがあり、適用ルーチンは次のとおりです。
plot(x,y) #默认为蓝色实线
plot(x,y,'go-') #带有圆圈标记的绿线
plot(x,y,'ks:') #带有正方形标记的黑色虚线
シンボル | 色 |
---|---|
「b」 | 青 |
「ぐ」 | 緑 |
「r」 | 赤 |
「c」 | 青 |
「ん」 | 赤紫色 |
「はい」 | 黄色 |
「k」 | 黒 |
「わ」 | 白 |
1.2.2 画像の輪郭とヒストグラム
from PIL import Image
from pylab import *
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
# 打开图像,并转成灰度图像
im = array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg').convert('L'))
# 新建一个图像
figure()
subplot(121)
# 不使用颜色信息
gray()
# 在原点的左上角显示轮廓图像
contour(im, origin='image')
axis('equal')
axis('off')
title(u'图像轮廓图', fontproperties=font)
subplot(122)
# 利用hist来绘制直方图
# 第一个参数为一个一维数组
# 因为hist只接受一维数组作为输入,所以要用flatten()方法将任意数组按照行优先准则转化成一个一维数组
# 第二个参数指定bin的个数
hist(im.flatten(), 128)
title(u'图像直方图', fontproperties=font)
# plt.xlim([0,250])
# plt.ylim([0,12000])
show()
1.2.3 インタラクティブな注釈
場合によっては、ユーザーは、画像をドットでマークしたり、トレーニング データに注釈を付けたりするなど、アプリケーションと対話する必要があることがあります。PyLab には、対話型の注釈を実現するための非常にシンプルで使いやすい関数 gitput() が用意されています。
from PIL import Image
from pylab import *
im = array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg'))
imshow(im)
print('Please click 3 points')
x = ginput(3)
print('you clicked:', x)
show()
出力:
you clicked:
[(118.4632306896458, 177.58271393177051),
(118.4632306896458, 177.58271393177051),
(118.4632306896458, 177.58271393177051)]
上記のコードは、最初に Empire.jpg イメージを読み取り、読み取ったイメージを表示し、次に ginput() を使用してインタラクティブに注釈を付けます。ここで設定されたインタラクティブ注釈データ ポイントは 3 に設定されます。ユーザーが注釈を付けた後、注釈ポイントの座標はプリントアウトされる。
1.3 NumPy ライブラリ
NumPy オンライン ドキュメント
NumPy は、科学計算用の人気のある Python パッケージです。これには、ベクトル、行列、画像、線形代数関数など、他にも多くの非常に便利なオブジェクトが含まれています。
1.3.1 画像配列表現
前の画像の例では、array() 関数を使用して画像を NumPy 配列オブジェクトに変換しましたが、その意味については触れていませんでした。配列はリストに似ていますが、配列内のすべての要素が同じ型でなければならないと規定されている点が異なります。特に指定がない限り、データ型はデータ型に従って自動的に決定されます。
例は次のとおりです。
from PIL import Image
from pylab import *
im = array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg'))
print (im.shape, im.dtype)
im = array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg').convert('L'),'f')
print (im.shape, im.dtype)
出力:
(800, 569, 3) uint8
(800, 569) float32
説明:
最初のタプルは画像配列のサイズ (行、列、カラー チャネル) を示し、
2 番目の文字列は配列要素のデータ型を示します。これは、画像は通常 8 ビットの符号なし整数としてエンコードされるためです。
- uint8: デフォルトのタイプ
- float32: 画像をグレースケールし、「f」パラメータを追加すると、浮動小数点型になります。
- 配列要素にアクセスする方法 - 添字アクセスを使用する
value=im[i,j,k]
- 複数の配列要素を送信する方法 - 配列スライスメソッドを使用してアクセスし、指定された間隔で添字によってアクセスされる配列の要素値を返します
im[i,:] = im[j,:] #将第j行的数值赋值给第i行
im[:,j] = 100 #将第i列所有数值设为100
im[:100,:50].sum() #计算前100行、前50列所有数值的和
im[50:100,50:100] #50~100行,50~100列,不包含第100行和100列
im[i].mean() #第i行所有数值的平均值
im[:,-1] #最后一列
im[-2,:]/im[-2] #倒数第二行
1.3.2 グレースケール変換
画像を NumPy 配列オブジェクトに読み込んだ後、それらに対して任意の数学演算を実行できます。簡単な例としては、画像のグレースケール変換が挙げられます。任意の関数 ff を考えてみましょう。f、それ自体に 0 ~ 255 をマッピングします。つまり、出力間隔は入力間隔と同じです。
例は次のとおりです。
from PIL import Image
from numpy import *
from pylab import *
im=array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg').convert('L'))
print(int(im.min()),int(im.max()))
im2=255-im #对图像进行反向处理
print(int(im2.min()),int(im2.max())) #查看最大/最小元素
im3=(100.0/255)*im+100 #将图像像素值变换到100...200区间
print(int(im3.min()),int(im3.max()))
im4=255.0*(im/255.0)**2 #对像素值求平方后得到的图像
print(int(im4.min()),int(im4.max()))
figure()
gray()
subplot(131)
imshow(im2)
axis('off')
title(r'$f(x)=255-x$')
subplot(132)
imshow(im3)
axis('off')
title(r'$f(x)=\frac{100}{255}x+100$')
subplot(133)
imshow(im4)
axis('off')
title(r'$f(x)=255(\frac{x}{255})^2$')
show()
出力:
3 255
0 252
101 200
0 255
- 配列変換の逆の操作は、PIL の fromarray() 関数を使用して実行できます。
pil_im=Image.fromarray(im)
- 前の操作で「uint8」データ型を別の型に変換した場合は、PIL イメージを作成する前にデータ型を変換し直す必要があります。
pil_im=Image.fromarray(uint8(im))
1.3.3 画像のスケーリング
NumPy 配列は画像やデータを操作するための主要なツールになりますが、行列のサイズを変更する簡単な方法はありません。PIL 画像オブジェクト変換を使用して、単純な画像サイズ変更関数を作成できます。
def imresize(im,sz):
""" Resize an image array using PIL. """
pil_im = Image.fromarray(uint8(im))
return array(pil_im.resize(sz))
上記で定義された調整関数は、imtools.py にあります。
1.3.4 ヒストグラムの等化
ヒストグラム等化とは、変換された画像内の各グレー値の分布確率が同じになるように、画像のグレー ヒストグラムを平坦化することを指します。この方法は、グレー値を正規化するための優れた方法であり、画像のコントラストを高めることができます。
- 変換関数: 画像内のピクセル値の累積分布関数 (cdf)、ピクセル値の範囲をターゲット範囲にマッピングする正規化操作
次の関数は、ヒストグラム等化の具体的な実装です。
def histeq(im,nbr_bins=256):
""" 对一幅灰度图像进行直方图均衡化"""
# 计算图像的直方图
imhist,bins = histogram(im.flatten(),nbr_bins,normed=True)
cdf = imhist.cumsum() # 累积分布函数
cdf = 255 * cdf / cdf[-1] # 归一化
# 此处使用到累积分布函数cdf的最后一个元素(下标为-1),其目的是将其归一化到0~1范围
# 使用累积分布函数的线性插值,计算新的像素值
im2 = interp(im.flatten(),bins[:-1],cdf)
return im2.reshape(im.shape), cdf
説明:
- この関数には 2 つのパラメータがあります
- グレースケール画像
- ヒストグラムで使用されるビンの数
- 関数の戻り値
- 均一化された画像
- ピクセル値マッピングの累積分布関数
プログラムの実装:
from PIL import Image
from pylab import *
from PCV.tools import imtools
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
im = array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg').convert('L'))
# 打开图像,并转成灰度图像
#im = array(Image.open('../data/AquaTermi_lowcontrast.JPG').convert('L'))
im2, cdf = imtools.histeq(im)
figure()
subplot(2, 2, 1)
axis('off')
gray()
title(u'原始图像', fontproperties=font)
imshow(im)
subplot(2, 2, 2)
axis('off')
title(u'直方图均衡化后的图像', fontproperties=font)
imshow(im2)
subplot(2, 2, 3)
axis('off')
title(u'原始直方图', fontproperties=font)
#hist(im.flatten(), 128, cumulative=True, normed=True)
hist(im.flatten(), 128, normed=True)
subplot(2, 2, 4)
axis('off')
title(u'均衡化后的直方图', fontproperties=font)
#hist(im2.flatten(), 128, cumulative=True, normed=True)
hist(im2.flatten(), 128, normed=True)
show()
結果:
1.3.5 画像の平均化
画像の平均化は、画像のノイズを低減する簡単な方法であり、芸術的な効果を生み出すためによく使用されます。すべての画像が同じサイズであると仮定すると、画像の同じ位置にあるピクセルを平均することができます。画像の平均を示す例は次のとおりです。
def compute_average(imlist):
""" 计算图像列表的平均图像"""
# 打开第一幅图像,将其存储在浮点型数组中
averageim = array(Image.open(imlist[0]), 'f')
for imname in imlist[1:]:
try:
averageim += array(Image.open(imname))
except:
print imname + '...skipped'
averageim /= len(imlist)
# 返回uint8 类型的平均图像
return array(averageim, 'uint8')
注: 一部の画像を開けず、平均結果が特定の画像または 2 つの画像の平均にすぎない可能性があります。
1.3.6 画像の主成分分析を実行する
PCA (主成分分析) は、非常に有用な次元削減手法です。これは、使用する次元をできるだけ少なくしながら、トレーニング データからできるだけ多くの情報を保存できるという意味で最適な手法です。100 × 100 ピクセルの小さなグレースケール画像でも 10,000 次元があり、10,000 次元空間内の点と見なすことができます。メガピクセルの画像には数百万の次元があります。画像の次元数が高いため、多くのコンピューター ビジョン アプリケーションでは次元削減操作がよく使用されます。PCA によって生成される射影行列は、元の座標を既存の座標系に変換したものとみなすことができ、座標系内の各座標は重要度の高い順に配置されます。
画像データに対して PCA 変換を実行するには、画像を 1 次元のベクトル表現に変換する必要があります。NumPy クラス ライブラリのメソッドを使用してflatten()
変換を実行できます。
平坦化された画像を積み重ねることにより、行列を取得できます。行列の 1 行が画像を表します。すべての行イメージは、主方向を計算する前に平均イメージによって中心化されます。通常、主成分の計算には SVD (Singular Value Decomposition、特異値分解) 法を使用しますが、行列の次元が大きい場合、SVD の計算は非常に遅くなるため、現時点では通常 SVD 分解は使用されません。 。
PCA 操作のコードは次のとおりです。
from PIL import Image
from numpy import *
def pca(X):
""" 主成分分析:
输入:矩阵X ,其中该矩阵中存储训练数据,每一行为一条训练数据
返回:投影矩阵(按照维度的重要性排序)、方差和均值"""
# 获取维数
num_data,dim = X.shape
# 数据中心化
mean_X = X.mean(axis=0)
X = X - mean_X
if dim>num_data:
# PCA- 使用紧致技巧
M = dot(X,X.T) # 协方差矩阵
e,EV = linalg.eigh(M) # 特征值和特征向量
tmp = dot(X.T,EV).T # 这就是紧致技巧
V = tmp[::-1] # 由于最后的特征向量是我们所需要的,所以需要将其逆转
S = sqrt(e)[::-1] # 由于特征值是按照递增顺序排列的,所以需要将其逆转
for i in range(V.shape[1]):
V[:,i] /= S
else:
# PCA- 使用SVD 方法
U,S,V = linalg.svd(X)
V = V[:num_data] # 仅仅返回前nun_data 维的数据才合理
# 返回投影矩阵、方差和均值
return V,S,mean_X
この関数はまず各次元の平均を減算してデータを中心化し、次に共分散行列の最大の固有値に対応する固有ベクトルを計算します。これは簡潔なトリックまたは SVD 分解を使用して実行できます。ここでは range() 関数を使用します。この関数の入力パラメータは整数 n で、この関数は整数 0...(n-1) のリストを返します。arange() 関数を使用して配列を返したり、xrange() 関数を使用してジェネレーターを返したりすることもできます (おそらく速度向上のため)。この本では range() 関数を使用します。
データの数がベクトルの次元よりも小さい場合、SVD 分解の代わりに、より小さい次元の共分散行列 XXT の固有ベクトルを計算します。上記の PCA 演算は、上位 k (k は次元を縮小したもの) の最大固有値に対応する固有ベクトルのみを計算することで高速化できます。スペースに限りがあるため、興味のある読者はご自身で探索していただけます。行列 V のベクトルの各行は直交しており、トレーニング データの分散が順番に減少する座標方向が含まれています。
次に、フォント イメージに対して PCA 変換を実行します。fontimages.zip ファイルには、さまざまなフォントでの文字 a のサムネイル イメージが含まれています。2359 フォントすべてが無料でダウンロードできます2。これらのイメージの名前がリスト imlist に格納されており、このリストは前のコードと一緒に pca.py ファイルに保存されていると仮定すると、次のスクリプトを使用してイメージの主成分を計算できます。
import pickle
from PIL import Image
from numpy import *
from pylab import *
from PCV.tools import imtools,pca
# Uses sparse pca codepath
# 获取图像列表和尺寸
imlist=imtools.get_imlist('E:/python/Python Computer Vision/Image data/fontimages/a_thumbs')
# open ont image to get the size
im=array(Image.open(imlist[0]))
# get the size of the images
m,n=im.shape[:2]
# get the number of images
imnbr=len(imlist)
print("The number of images is %d" % imnbr)
# create matrix to store all flattened images
immatrix = array([array(Image.open(imname)).flatten() for imname in imlist],'f')
# PCA降维
V,S,immean=pca.pca(immatrix)
# 保存均值和主成分
#f = open('../ch01/font_pca_modes.pkl', 'wb')
#pickle.dump(immean,f)
#pickle.dump(V,f)
#f.close()
# Show the images (mean and 7 first modes)
# This gives figure 1-8 (p15) in the book.
figure()
gray()
subplot(241)
axis('off')
imshow(immean.reshape(m,n))
for i in range(7):
subplot(2,4,i+2)
imshow(V[i].reshape(m,n))
axis('off')
show()
これらのイメージを 1 次元表現に取り込んだ後、 reshape() 関数を使用して元に戻す必要があることに注意してください。上記のコードを実行すると、元の本の P15 図 1-8 にある結果が得られます。
1.3.7 ピクルスモジュール
Python のモジュールはpickle
、後で使用するために結果やデータを保存したい場合に非常に便利です。pickle
モジュールは、ほぼすべての Python オブジェクトを受け入れ、それを文字列表現に変換できます。これは、ピクルスと呼ばれるプロセスです。文字列表現からオブジェクトを再構築することは、アンピックリングと呼ばれます。これらの文字列表現は、簡単に保存および送信できます。
例を見てみましょう。前のセクションのフォント イメージの平均イメージと主成分を保存したいと仮定すると、これは次のように実行できます。
# 保存均值和主成分数据
f = open('font_pca_modes.pkl','wb')
pickle.dump(immean,f)
pickle.dump(V,f)
f.close()
上の例では、多数のオブジェクトを同じファイルに保存できます。pickle
モジュールには.pkl
ファイルを生成できるさまざまなプロトコルが存在します。よくわからない場合は、バイナリ ファイルとして読み書きすることをお勧めします。他の Python セッションにデータをロードするには、load()
次のようにメソッドを使用します。
# 载入均值和主成分数据
f = open('font_pca_modes.pkl','rb')
immean = pickle.load(f)
V = pickle.load(f)
f.close()
オブジェクトは、以前に保存したときと同じ順序でロードする必要があることに注意してください。cpickle
C で書かれた Python には、モジュールと呼ばれる最適化されたバージョンがあり、pickle
標準モジュールと完全に互換性があります。pickle モジュールの詳細については、http://docs.python.org/library/pickle.html にある pickle モジュールのドキュメント ページを参照してください。
この本の残りの部分では、with ステートメントを使用してファイルの読み取りと書き込みを処理します。これは、(ファイルを開くときにエラーが発生した場合でも) ファイルを自動的に開閉するために Python 2.5 で導入されたアイデアです。次の例では、with()
保存操作と読み込み操作を実装するために使用します。
# 打开文件并保存
with open('font_pca_modes.pkl', 'wb') as f:
pickle.dump(immean,f)
pickle.dump(V,f)
と
# 打开文件并载入
with open('font_pca_modes.pkl', 'rb') as f:
immean = pickle.load(f)
V = pickle.load(f)
上の例は最初は奇妙に思えるかもしれませんが、with() は非常に便利なアイデアです。それが気に入らない場合は、以前の開閉機能を使用できます。
NumPy には、 の代わりにpickle
、テキスト ファイルの読み取りと書き込みを行うための単純な関数があります。NumPy の読み取りおよび書き込み関数は、画像上でクリックされた点のリストなど、データに複雑なデータ構造が含まれていない場合に役立ちます。配列 x をファイルに保存するには、次を使用します。
savetxt('test.txt',x,'%i')
最後のパラメータは、整数形式を使用する必要があることを示します。同様に、読み取りは次を使用して実行できます。
x = loadtxt('test.txt')
オンラインドキュメントから詳細を学ぶことができます
最後に、NumPy には配列の保存と読み込みのための専用関数があります。詳細についてsave()
は、オンライン ドキュメントを参照してください。load()
1.4 サイピー
SciPy (http://scipy.org/) は、NumPy に基づく数値演算のためのオープンソース ツールキットです。SciPy は、数値積分、最適化、統計、信号処理、そして私たちにとって最も重要な画像処理のための多くの効率的な操作を提供します。
1.4.1 ぼやけた画像
画像のガウスぼかしは、画像畳み込みの非常に古典的な例です。基本的に、画像のぼかしは、(グレースケール) 画像 $I$ とガウス カーネルの畳み込みです。
このうち、*は畳み込みを意味し、G δ G_\deltaGd標準偏差がδ \deltaであることを示しますデルタコンボリューションカーネル
- フィルタ操作モジュール——
scipy.ndimage.filters
このモジュールは、高速 1 次元分離を使用して畳み込みを計算できます。使用方法は次のとおりです。
from PIL import Image
from numpy import *
from pylab import *
from scipy.ndimage import filters
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font=FontProperties(fname=r"c:\windows\fonts\SimSun.ttc",size=14)
im=array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg').convert('L'))
figure()
gray()
axis('off')
subplot(141)
axis('off')
title(u'原图',fontproperties=font)
imshow(im)
for bi,blur in enumerate([2,5,10]):
im2=zeros(im.shape)
im2=filters.gaussian_filter(im,blur)
im2=np.uint8(im2)
imNum=str(blur)
subplot(1,4,2+bi)
axis('off')
title(u'标准差为'+imNum,fontproperties=font)
imshow(im2)
#如果是彩色图像,则分别对三个通道进行模糊
#for bi, blur in enumerate([2, 5, 10]):
# im2 = zeros(im.shape)
# for i in range(3):
# im2[:, :, i] = filters.gaussian_filter(im[:, :, i], blur)
# im2 = np.uint8(im2)
# subplot(1, 4, 2 + bi)
# axis('off')
# imshow(im2)
show()
上の最初の画像はぼかしをかける画像、2 番目の画像はガウス標準偏差 2 でぼかし、3 番目の画像はガウス標準偏差 5 でぼかし、最後の画像はガウス標準偏差 10 でぼかします。 。このモジュールの使用法とパラメータ選択の詳細については、SciPy scipy.ndimage ドキュメントを参照してください。
1.4.2 画像の派生画像
画像強度の変化は、多くのアプリケーションにおいて非常に重要な情報です。グレースケール画像で強度の変更が可能IIxxのI (カラー イメージの場合、導関数は通常、カラー チャネルごとに個別に計算されます)xと $y$ の方向導関数I x I_x私×説明として $I_y$ を付けます。
- 画像の勾配ベクトルは∇ I = [ I x , I y ] T ∇ I = [I_x, I_y]^Tです。∇私=[私×、私はい】Tは、各ピクセル上で画像の強度が最も大きく変化する方向を表します。
- グラデーションには 2 つの重要なプロパティがあります。
- 梯度的大小:
∣ ∇ I ∣ = I x 2 + I y 2 |∇I| = \sqrt {I_x^2+I_y^2} ∣∇私∣=私バツ2+私y2 - 勾配の方向:
α = arctan 2 ( I x , I y ) \alpha=arctan2(I_x, I_y)ある=arc t an 2 (私_×、私はい)
NumPy
の関数はarctan2()
ラジアンで表された符号付き角度を返します。角度の変更範囲は[ − π , π ] [-\pi,\pi]です。[ − π ,p ]
離散近似で画像の導関数を計算できます。画像導関数は、ほとんどの場合、単純に畳み込みによって実装できます:
I x = I ∗ D x I_x=I*D_x私×=私∗D×,I y = I ∗ D y I_y=I*D_y私はい=私∗Dはい
通常、prewitt フィルターまたは sobel フィルターが選択されますが、
これらの微分フィルターは、scipy.ndimage.filters
モジュールの標準的な畳み込み演算を使用して簡単に実装できます。
from PIL import Image
from pylab import *
from scipy.ndimage import filters
import numpy
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font=FontProperties(fname=r"c:\windows\fonts\SimSun.ttc",size=14)
im=array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg').convert('L'))
gray()
subplot(141)
axis('off')
title(u'(a)原图',fontproperties=font)
imshow(im)
# sobel derivative filters
imx=zeros(im.shape)
filters.sobel(im,1,imx)
subplot(142)
axis('off')
title(u'(b)x方向差分',fontproperties=font)
imshow(imx)
imy=zeros(im.shape)
filters.sobel(im,0,imy)
subplot(143)
axis('off')
title(u'(c)y方向差分',fontproperties=font)
imshow(imy)
mag=255-numpy.sqrt(imx**2+imy**2)
subplot(144)
title(u'(d)梯度幅值',fontproperties=font)
axis('off')
imshow(mag)
show()
ガウスの違い:
from PIL import Image
from pylab import *
from scipy.ndimage import filters
import numpy
# 添加中文字体支持
#from matplotlib.font_manager import FontProperties
#font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
def imx(im, sigma):
imgx = zeros(im.shape)
filters.gaussian_filter(im, sigma, (0, 1), imgx)
return imgx
def imy(im, sigma):
imgy = zeros(im.shape)
filters.gaussian_filter(im, sigma, (1, 0), imgy)
return imgy
def mag(im, sigma):
# there's also gaussian_gradient_magnitude()
#mag = numpy.sqrt(imgx**2 + imgy**2)
imgmag = 255 - numpy.sqrt(imgx ** 2 + imgy ** 2)
return imgmag
im = array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg').convert('L'))
figure()
gray()
sigma = [2, 5, 10]
for i in sigma:
subplot(3, 4, 4*(sigma.index(i))+1)
axis('off')
imshow(im)
imgx=imx(im, i)
subplot(3, 4, 4*(sigma.index(i))+2)
axis('off')
imshow(imgx)
imgy=imy(im, i)
subplot(3, 4, 4*(sigma.index(i))+3)
axis('off')
imshow(imgy)
imgmag=mag(im, i)
subplot(3, 4, 4*(sigma.index(i))+4)
axis('off')
imshow(imgmag)
show()
1.4.3 形態学: オブジェクトのカウント
形態学 (または数学的形態学) は、基本的な形状を測定および分析するための基本的なフレームワークおよび画像処理方法の集合です。形態学は通常、バイナリ イメージに使用されますが、グレースケール イメージにも使用できます。バイナリ イメージとは、イメージの各ピクセルが 2 つの値 (通常は 0 と 1) のみを取ることを意味します。バイナリ イメージは、通常、オブジェクトを数えたり、そのサイズを測定したりするときに、イメージをしきい値処理した結果です。形態学の概要と画像の処理方法については、http://en.wikipedia.org/wiki/Mathematical_morphology で読むことができます。
scipy.ndimage
のモジュールはmorphology
モルフォロジー演算を実現できます。のモジュール
scipy.ndimage
はmeasurements
バイナリ画像の計数および測定機能を実現できます。
これらの使用方法の簡単な例を次に示します。
from scipy.ndimage import measurements,morphology
# 载入图像,然后使用阈值化操作,以保证处理的图像为二值图像
im = array(Image.open('houses.png').convert('L'))
im = 1*(im<128)
labels, nbr_objects = measurements.label(im)
print "Number of objects:", nbr_objects
- 上記のスクリプトは、最初にイメージをロードし、それがバイナリ イメージであることを確認するためにしきい値を設定します。スクリプトは、ブール配列を 1 で乗算してバイナリ表現に変換します。
- 次に、label() 関数を使用して個々のオブジェクトを検索し、どのオブジェクトに属しているかに応じてピクセルに整数のラベルを割り当てます。
- 図 1-12b は、ラベル配列のイメージです。画像のグレースケール値はオブジェクトのラベルを表します。ご覧のとおり、いくつかのオブジェクト間には小さなつながりがあります。バイナリをオープンすると、それを削除できます。
# 形态学开操作更好地分离各个对象
im_open = morphology.binary_opening(im,ones((9,5)),iterations=2)
labels_open, nbr_objects_open = measurements.label(im_open)
print "Number of objects:", nbr_objects_open
-
binary_opening()
関数の 2 番目のパラメーターは、配列構造要素を指定します。 -
この配列は、ピクセルを中心とするときにどの隣接ピクセルを使用するかを示します。
-
この場合、y 方向に 9 ピクセル (上に 4 ピクセル、ピクセル自体、下に 4 ピクセル)、x 方向に 5 ピクセルを使用します。構造要素として任意の配列を指定でき、配列内のゼロ以外の要素によって、どの隣接ピクセルが使用されるかが決まります。
-
パラメーターの反復により、操作を実行する回数が決まります。さまざまな反復値を試して、オブジェクトの数がどのように変化するかを確認できます。
-
開いたイメージと、対応するラベル イメージを図 1-12c および図 1-12d に示します。
-
binary_closing()
関数はその逆を行います。 -
この関数と形態学および測定モジュールの他の関数の使用法は演習として残しておきます。これらの関数の詳細については、scipy.ndimage モジュールのドキュメントを参照してください。
from PIL import Image
from numpy import *
from scipy.ndimage import measurements, morphology
from pylab import *
""" This is the morphology counting objects example in Section 1.4. """
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
# load image and threshold to make sure it is binary
figure()
gray()
im = array(Image.open('E:/python/Python Computer Vision/Image data/houses.png').convert('L'))
subplot(221)
imshow(im)
axis('off')
title(u'原图', fontproperties=font)
im = (im < 128)
labels, nbr_objects = measurements.label(im)
print ("Number of objects:", nbr_objects)
subplot(222)
imshow(labels)
axis('off')
title(u'标记后的图', fontproperties=font)
# morphology - opening to separate objects better
im_open = morphology.binary_opening(im, ones((9, 5)), iterations=2)
subplot(223)
imshow(im_open)
axis('off')
title(u'开运算后的图像', fontproperties=font)
labels_open, nbr_objects_open = measurements.label(im_open)
print ("Number of objects:", nbr_objects_open)
subplot(224)
imshow(labels_open)
axis('off')
title(u'开运算后进行标记后的图像', fontproperties=font)
show()
出力:
Number of objects: 45
Number of objects: 48
1.4.4 便利な SciPy モジュール
SciPy
入出力用の便利なモジュールがいくつか含まれています。これらのモジュールのうち 2 つについては以下で説明しますio
。misc
1. .mat ファイルの読み取りと書き込み
データがある場合、またはインターネットから興味深いデータ セットをダウンロードした場合、これらのデータは Matlab の .mat ファイル形式で保存されているため、scipy.io モジュールを使用して読み取ることができます。
data = scipy.io.loadmat('test.mat')
上記のコードでは、データ オブジェクトには、キーが元の .mat ファイルに格納されている変数名に対応する辞書が含まれています。これらの変数は配列形式であるため、.mat ファイルに保存すると便利です。保存したいすべての変数を含む辞書を作成し、savemat() 関数を使用するだけです。
data = {}
data['x'] = x
scipy.io.savemat('test.mat',data)
上記のスクリプトは配列 x を保存するため、それが Matlab に読み込まれるとき、変数の名前は x のままです。scipy.io
モジュールの詳細については、オンライン ドキュメントを参照してください。
2. 配列を画像として保存します
画像を操作する必要があり、操作には配列オブジェクトを使用する必要があるため、配列を画像ファイルとして直接保存すると非常に便利です4。この本に掲載されている画像の多くはこの方法で作成されました。
imsave()
機能:scipy.misc
モジュールからロードされます。im
配列をファイルに保存するには、次のコマンドを使用します。
from scipy.misc import imsave
imsave('test.jpg',im)
scipy.misc
このモジュールには、有名な Lena テスト イメージも含まれています。
lena = scipy.misc.lena()
スクリプトはグレースケール画像の 512x512 配列を返します。
画像ウィンドウの「保存」ボタンをクリックすると、すべての Pylab プロットをさまざまな画像形式で保存できます。
1.5 高度な例: 画像のノイズ除去
この章は、画像のノイズ除去という非常に実践的な例で終わります。画像のノイズ除去は、画像のノイズを除去しながら、画像の詳細と構造を可能な限り保存する処理技術です。ここでは ROF (Rudin-Osher-Fatemi) ノイズ除去モデルを使用します。このモデルは文献に初めて登場しました [28]。画像のノイズ除去は、休暇中の写真の見栄えを良くすることから衛星画像の品質の向上に至るまで、多くの用途にとって重要です。ROF モデルには、画像のエッジや構造情報を維持しながら、処理された画像をより滑らかにするという優れた特性があります。
ROF モデルの数学的基礎と処理技術は高度すぎるため、本書ではカバーできません。Chambolle [5] によって提案されたアルゴリズムに基づいて ROF ソルバーを実装する方法を説明する前に、本書ではまず ROF モデルを簡単に紹介します。
ノイズ除去合成の例:
from pylab import *
from numpy import *
from numpy import random
from scipy.ndimage import filters
from scipy.misc import imsave
from PCV.tools import rof
""" This is the de-noising example using ROF in Section 1.5. """
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
# create synthetic image with noise
im = zeros((500,500))
im[100:400,100:400] = 128
im[200:300,200:300] = 255
im = im + 30*random.standard_normal((500,500))
U,T = rof.denoise(im,im)
G = filters.gaussian_filter(im,10)
# save the result
#imsave('synth_original.pdf',im)
#imsave('synth_rof.pdf',U)
#imsave('synth_gaussian.pdf',G)
# plot
figure()
gray()
subplot(1,3,1)
imshow(im)
#axis('equal')
axis('off')
title(u'原噪声图像', fontproperties=font)
subplot(1,3,2)
imshow(G)
#axis('equal')
axis('off')
title(u'高斯模糊后的图像', fontproperties=font)
subplot(1,3,3)
imshow(U)
#axis('equal')
axis('off')
title(u'ROF降噪后的图像', fontproperties=font)
show()
最初の画像は元のノイズ画像を示し、中央の画像は標準偏差 10 のガウスぼかしの結果を示し、一番右の画像は ROF ノイズ低減後の画像を示します。上の元のノイズ イメージはシミュレートされたイメージですが、実際のイメージでテストします。
from PIL import Image
from pylab import *
from numpy import *
from numpy import random
from scipy.ndimage import filters
from scipy.misc import imsave
from PCV.tools import rof
""" This is the de-noising example using ROF in Section 1.5. """
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
im = array(Image.open('E:/python/Python Computer Vision/Image data/empire.jpg').convert('L'))
U,T = rof.denoise(im,im)
G = filters.gaussian_filter(im,10)
# save the result
#imsave('synth_original.pdf',im)
#imsave('synth_rof.pdf',U)
#imsave('synth_gaussian.pdf',G)
# plot
figure()
gray()
subplot(1,3,1)
imshow(im)
#axis('equal')
axis('off')
title(u'原噪声图像', fontproperties=font)
subplot(1,3,2)
imshow(G)
#axis('equal')
axis('off')
title(u'高斯模糊后的图像', fontproperties=font)
subplot(1,3,3)
imshow(U)
#axis('equal')
axis('off')
title(u'ROF降噪后的图像', fontproperties=font)
show()
ROF ノイズ リダクションによりエッジと画像構造を維持できる
1.6 PCVパッケージのインストール
-
PCVライブラリファイルデータのダウンロード、ダウンロードアドレス:https://github.com/jesolem/PCV
-
ダウンロードしたファイルを C:\Users\Administrator\Desktop\PCV に解凍します。
-
cmd を開き、次のコマンドを実行します。
(1)cd C:\Users\Administrator\Desktop\PCV
(2)python setup.py インストール
-
pycharm に入力して
import PCV
インストールが成功したかどうかをテストします
エラー 1 が報告された場合:に変更しますNameError: name 'file' is not defined
。fp = file(filename, 'wb')
fp = open(filename, 'wb')
エラー 2: が報告された場合はTypeError: write() argument must be str, not bytes
、ファイルを開く方法に問題があります。バイナリ モードで開くように前の開始ステートメントを変更するだけです。
filelist = get_imlist('E:/python/Python Computer Vision/test jpg/') #获取convert_images_format_test文件夹下的图片文件名(包括后缀名)
imlist = open('E:/python/Python Computer Vision/test jpg/imlist.txt','wb+')