Python画像処理の一般的な操作上の注意
自己問診に便利な孟新のメモ、よく使われる方法を記録し、随時更新していきます〜
1.静止画の操作に関する注意事項
ライブラリをインストールします
インストール
pip install numpy
pip install opencv-python
ライブラリをインポートする
import numpy as np
import cv2
静止画像の読み取りと書き込み
注:画像ファイル名に中国語が含まれている場合、エラーが発生し、コーディングの問題である可能性があります。
ディスクから画像を読み取る
img_path = "input.jpg"
# 读取单通道黑白图片
img = cv2.imread(img_path,0)
# 读取三通道彩色图片
img = cv2.imread(img_path,1)
# 读取四通道PNG图片,第四通道alpha为透明度
img_path = "input.png"
img = cv2.imread(img_path,-1)
ディスクに画像を書き込む
output_path = "output.jpg"
cv2.imwrite(output_path,img)
cv2で画像を表示する
# 允许图片自由缩放
window_name = "test window"
cv2.namedWindow(window_name,0);
# 显示图片
cv2.imshow(window_name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
カラー画像をグレースケール画像に変換する
注:効果は、グレースケール画像を直接読み取る場合とまったく同じではありません。
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
画像のノイズをフィルタリングする
特定のニーズに応じて異なるフィルターを選択します。
# 使用3x3的均值滤波器
img = cv2.blur(img, (3, 3))
# 中值滤波
img = cv2.medianBlur(img, 3)
# 高斯滤波
img = cv2.GaussianBlur(img,(3,3),0)
# 自定义滤波器,样例为拉普拉斯滤波器
kernal = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])
img = cv2.filter2D(img, -1, kernal)
画像の長さと幅を拡大縮小する
サイズ変更は形状変更とは異なります。形状変更とは
、(2、3)を(1、6)に変更するなど、データの総量を変更せずにマトリックスを形状変更することです。
サイズ変更とは、画像を任意の縮尺でズームすることです。これにより、マトリックスに含まれる要素の総数が変更されます。
# 设定新的图片长宽
new_size = (224,224)
# 缩放图片
img = cv2.resize(img,new_size)
写真のキャプチャ
これは、次のようなnumpyの高次元マトリックススライスと同等です。
img = img[:200,100:,:]
カラーチャネルの分割とマージ
# 三颜色通道拆分
(B, G, R) = cv2.split(img)
# 三颜色通道合并
img = cv2.merge([B,G,R])
# 四颜色通道拆分
(B, G, R, A) = cv2.split(img)
# 四颜色通道合并
img = cv2.merge([B,G,R,A])
ヒストグラム均等化
# 对单通道使用,多通道需要先拆分再对每个通道分别均衡化
img = cv2.equalizeHist(img)
ピクチャーフリップ
# 垂直翻转
img = cv2.flip(img,0)
# 水平翻转
img = cv2.flip(img,1)
# 垂直水平翻转
img = cv2.flip(img,-1)
形態学的操作
# 定义核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
# 膨胀
img = cv2.dilate(img,kernel,iterations=1)
# 腐蚀
img = cv2.erode(img,kernel,iterations=1)
二値化
# 定义阈值
threshold = 50
# 二值化
ret,img=cv2.threshold(img,threshold,255,cv2.THRESH_BINARY_INV)
高次元行列転置
機械学習入力に使用されます。
(長さ、幅、3)のカラー画像マトリックスを(3、長さ、幅)の形式に変更します。
テンソルでの使用には、トーチパッケージをインポートする必要があります。
img = torch.tensor(img, dtype=torch.float32)
# 改变矩阵形状
img = img.permute(2, 0, 1)
2.ダイナミック画像操作ノート
アニメーションGIF画像のアクション
ライブラリをインストールします
インストール
pip install imageio
ライブラリをインポートする
import imageio
gif画像を読む
注:これはmimread()であり、imread()ではありません。
imgs = imageio.mimread("test.gif")
imgs = np.array(imgs)
現時点では、imgsはnumpyマトリックス形式のすべての画像を含むリストであり、各要素はnumpyマトリックス形式の画像です。
gif画像を書く
output_name = "output.gif"
imageio.mimsave(output_name, imgs, 'GIF')
3.いくつかの簡単な関数実現ノート
3.1モノクロの背景写真の背景色の置き換え
身分証明書の背景色を単色(青など)から別の色(白など)に置き換えるために使用します。背景と同じ色の服がキャラクターにほとんど含まれていない場合に使用します。
出力画像の効果に応じて、しきい値max_differenceのサイズを調整する必要があります。
import cv2
import numpy as np
from scipy.spatial.distance import cdist
# 输入文件名
input_img = 'input.jpg'
img = cv2.imread(input_img,1)
# 配置阈值,与取样点之间的最大相似值误差,根据输出效果调整
max_difference = 150
# 取出左上角第一个点作为取样点
sample = img[0][0]
# 将图片拉平用于计算
input_data = img.reshape((img.shape[0] * img.shape[1], 3))
# 计算所有图片与采样点之间的曼哈顿距离
differences = cdist(input_data, [sample], 'cityblock')
# 还原距离矩阵的形状,此时为单通道,仅包含距离
differences = differences.reshape((img.shape[0], img.shape[1]))
# 将背景替换为新的颜色,此处设置为白色
change = np.array([255,255,255])
# 深拷贝一个输入图片用于输出
output = img.copy()
for i in range(img.shape[0]):
# 打印工作进度
if i % 500 == 0:
print(i,"/",img.shape[0])
# 如果距离小于阈值,改变颜色
for j in range(img.shape[1]):
if differences[i][j] < max_difference:
output[i][j] = change
# 输出文件名
output_name = 'output.jpg'
cv2.imwrite(output_name,output)
3.2画像に透明レイヤーを追加し、透明度をカスタマイズします
3チャンネルのカラー画像を入力し、透明度の4番目のチャンネル(アルファチャンネル)を手動で追加し、透明度データをカスタマイズしてから、png画像として出力します。
import numpy as np
import cv2
# 输入一个三通道图像
img = cv2.imread('test.jpg',1)
# 拆分颜色通道
(B, G, R) = cv2.split(img)
# 自定义一个初始全为0的透明度图层
A = np.zeros(B.shape, dtype="uint8")
# 自定义调整透明度,透明度在0-255之间取值
# 这里将图片的一部分透明度调整为155,其余部分保持为0用作示例
A[:70,:] = 155
# 将透明度图层并入四通道图像
img = cv2.merge([B, G, R, A])
# 输出png格式的图片
cv2.imwrite('output.png',img)
3.3スクリーンショットを撮ってWeChatの絵文字を抽出する
3.1と3.2のコードのアイデアを統合して、スクリーンショットを使用してWeChatチャットで絵文字の写真を取得することを実現します...愚かなWeChatの絵文字の写真をローカルに直接保存することはできませんか???、そしてプログラムにスクリーンショットの背景を自動的に削除させ、元の透明な画像の背景を透明な状態として出力して、他の人の画像を自分のアバターとして盗むという邪悪な目的を達成します。
import numpy as np
import cv2
from scipy.spatial.distance import cdist
# config,配置参数,根据实际输出情况调整
# 在截图的四周切除百分之多少的边框
cut_percent = 4
# 配置阈值,与取样点之间的最大相似值误差
max_difference = 50
# 输入文件名
input_img = 'weixin_img.png'
# 输出文件名
output_name = 'output.png'
img = cv2.imread(input_img,1)
# 去除截图边缘边框(按照百分比切除)
img = img[int(img.shape[0]*(cut_percent/100)):int(img.shape[0]*(1-cut_percent/100)),\
int(img.shape[1]*(cut_percent/100)):int(img.shape[1]*(1-cut_percent/100)),:]
# 取出左上角第一个点作为取样点
sample = img[0][0]
# 将图片拉平用于计算
input_data = img.reshape((img.shape[0] * img.shape[1], 3))
# 计算所有图片与采样点之间的曼哈顿距离
differences = cdist(input_data, [sample], 'cityblock')
# 还原距离矩阵的形状,此时为单通道,仅包含距离
differences = differences.reshape((img.shape[0], img.shape[1]))
# 创建透明图层,默认全透明
A = np.zeros(img.shape[:2], dtype="uint8")
for i in range(img.shape[0]):
# 打印工作进度
if i % 500 == 0:
print(i,"/",img.shape[0])
# 如果距离大于阈值,设置为不透明
for j in range(img.shape[1]):
if differences[i][j] > max_difference:
A[i][j] = 255
# 生成带有透明图层的四通道输出图片
(B, G, R) = cv2.split(img)
output = cv2.merge([B, G, R, A])
cv2.imwrite(output_name,output)
3.4カラー画像を白黒の線画に変換する
グレースケール画像に変換し、ラプラシアンフィルターを介してラインドラフトの輪郭を抽出し、構造を接続し、形態学的操作の拡大と侵食によってノイズを除去し、最後に2値化を使用して輪郭を強調し、ノイズを低減しました。
元の画像:
import cv2
import numpy as np
img_path = "input.png"
# 读取单通道黑白图片
img = cv2.imread(img_path,0)
# 拉普拉斯滤波器
kernal = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])
img = cv2.filter2D(img, -1, kernal)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
# 膨胀两次
img = cv2.dilate(img,kernel,iterations=2)
# 腐蚀两次
img = cv2.erode(img,kernel,iterations=2)
# 二值化
ret,img=cv2.threshold(img,50,255,cv2.THRESH_BINARY_INV)
# 输出
output_path = "output.jpg"
cv2.imwrite(output_path,img)
最終効果: