メモ > 技術 > プログラミング言語: Python > OpenCV(画像処理)
OpenCV(画像処理)
OpenCV(Open Source Computer Vision Library)
画像や動画を処理するのに必要な様々な機能を提供するライブラリ。
Pythonを用いた画像処理(openCV,skimage) - Qiita
https://qiita.com/taka_baya/items/453e429b466ffaa702c9
Pythonで画像処理: Pillow, NumPy, OpenCVの違いと使い分け | note.nkmk.me
https://note.nkmk.me/python-image-processing-pillow-numpy-opencv/
■開発環境を構築
Windowsの場合は、このファイル内の「Windows上に開発環境を構築」を参照。
Linuxの場合は、RaspberryPi.txt の「OpenCV」を参照。
■画像の読み込みと表示
保存の際に拡張子を「.png」にすればPNG形式で保存される。
「.jpg」ならJpeg形式で保存される。
import cv2
img = cv2.imread("sample.jpg")
cv2.imwrite("output.png", img)
■画像のグレースケール変換
import cv2
img = cv2.imread("sample.png", 0)
cv2.imwrite('gray.png', img)
import cv2
img = cv2.imread("sample.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite("gray.png", img)
■画像の指定範囲の色を抽出
import cv2
import numpy as np
img = cv2.imread("sample.png", 1)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 取得する色の範囲を指定する
lower_color = np.array([20, 50, 50])
upper_color = np.array([255, 255, 255])
# 指定した色に基づいたマスク画像の生成
img_mask = cv2.inRange(hsv, lower_color, upper_color)
# フレーム画像とマスク画像の共通の領域を抽出する。
img_color = cv2.bitwise_and(img, img, mask=img_mask)
cv2.imwrite("hsv.png", img_color)
■画像のエッジ部分を抽出
import cv2
import numpy as np
# 白黒画像で画像を読み込み
img = cv2.imread("sample.png", 0)
# エッジ検出
canny_img = cv2.Canny(img, 50, 110)
cv2.imwrite("canny.png", canny_img)
■画像のネガポジ変換
import cv2
img = cv2.imread("face.png")
#img = 256 - img
img = 0 - img
cv2.imwrite("invert.png", img)
■画像のリサイズ
import cv2
# 画像を読み込み
img = cv2.imread("sample.png")
# リサイズ
img = cv2.resize(img, (80, 80))
cv2.imwrite("resize.png", img)
■画像のトリミング
import cv2
# 画像を読み込み
img = cv2.imread("sample.png")
# トリミング
x, y = 180, 240
w, h = 200, 60
img = img[y:y+h, x:x+w]
cv2.imwrite("trimming.png", img)
■画像の特異点を抽出
import cv2
import numpy as np
# 画像を読み込み
img = cv2.imread("sample.png", 1)
# 特異点を抽出
detector = cv2.ORB_create()
keypoints = detector.detect(img)
# 画像に特徴点を書き込み
img_orb = cv2.drawKeypoints(img, keypoints, None)
cv2.imwrite("orb.png", img_orb)
■画像のヒストグラムを可視化
import cv2
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
# 画像を読み込み
img = cv2.imread('sample.png')
# ヒストグラムを可視化
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv2.calcHist([img],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.savefig('histogram.png')
■輪郭抽出
import cv2
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
# 画像を読み込んでリサイズ
img = cv2.imread("face.jpg")
img = cv2.resize(img, (200, 300))
# 色空間を二値化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # グレースケールに変換
gray = cv2.GaussianBlur(gray, (7, 7), 0) # 平滑化
im2 = cv2.threshold(gray, 140, 240, cv2.THRESH_BINARY_INV)[1] # 二極化
# 画面左側に二値化した画像を描画
plt.subplot(1, 2, 1)
plt.imshow(im2, cmap="gray")
# 輪郭を抽出
cnts = cv2.findContours(im2,
cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)[0]
# 抽出した枠を描画
for pt in cnts:
x, y, w, h = cv2.boundingRect(pt)
# 大きすぎたり小さすぎたり領域を除去
if w < 30 or w > 200: continue
print(x,y,w,h) # 結果を出力
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 画面右側に抽出結果を描画
plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.savefig("found.png", dpi=200)
実行時に
「npoints = 0 && (depth == cv_32f depth == cv_32s) in function 'pointsetboundingrect'」
のようなエラーになった場合、findContoursの「[1]」を「[0]」にすれば動作した。
Opencv 3.2から仕様が変わり、関数の戻り値の数が変わったとのこと。
Python - 輪郭抽出プログラムが実行されません|teratail
https://teratail.com/questions/175238
■顔認識
#!/Users/refirio/Anaconda3/python
# coding: utf-8
# -*- coding: utf-8 -*-
import sys
import io
import cv2
# 使用ファイルと入出力ディレクトリ
IMAGE_FILE = "daughter.png"
INPUT_PATH = "./inputs/" + IMAGE_FILE
OUTPUT_PATH = "./outputs/" + IMAGE_FILE
# ラインの色
COLOR_WHITE = (255, 255, 255)
COLOR_RED = (0, 0, 255)
# 画像ファイル読み込み
image = cv2.imread(INPUT_PATH)
# 画像をグレースケール変換
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# カスケード分類器の特徴量を取得
face_cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_frontalface_alt.xml")
eye_cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_eye.xml")
# 画像の中から顔を検出
faces = face_cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=2, minSize=(50, 50))
if len(faces) > 0:
# 検出した顔の座標を取得
for (face_x,face_y,face_w,face_h) in faces:
# 検出した顔を囲む矩形の作成
cv2.rectangle(image, (face_x,face_y),(face_x + face_w,face_y + face_h), COLOR_WHITE, 2)
# 検出した顔画像を取得
face_image = image[face_y : face_y + face_h, face_x : face_x + face_w]
# 検出した顔画像をグレースケール変換
face_image_gray = image_gray[face_y : face_y + face_h, face_x : face_x + face_w]
# 顔画像の中から目を検出
eyes = eye_cascade.detectMultiScale(face_image_gray, scaleFactor=1.1, minNeighbors=2, minSize=(20, 20))
if len(faces) > 0:
# 検出した目の座標を取得
for (eye_x,eye_y,eye_w,eye_h) in eyes:
# 検出した目を囲む矩形の作成
cv2.rectangle(face_image,(eye_x, eye_y),(eye_x + eye_w,eye_y + eye_h), COLOR_RED, 2)
# 認識結果の保存
cv2.imwrite(OUTPUT_PATH, image)
# 結果画面を表示
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
print("Content-Type: text/html; charset=UTF-8\n")
print("<!DOCTYPE html>")
print("<html>")
print("<head>")
print("<meta charset=\"utf-8\">")
print("<title>Python</title>")
print("</head>")
print("<body>")
print("<h1>Python</h1>")
print("<img src=\"" + OUTPUT_PATH + "\" style=\"max-width: 500px; max-height: 500px;\">")
print("</body>")
print("</html>")