Pythonの画像アフィン変換戦闘抽出デジタル手書きサンプル

実際の戦闘プロジェクトを開始する前に、ナレッジポイント(接続されたドメインの外側の長方形)を学習しましょう

外接する四角形を見つける方法は2つあります。

  • 1つは、輪郭のエッジの部分を見つけて、最も外側の境界の四角形を見つけることです。これを区別するために、下の緑の四角形の部分に示すように、これをboundingRectと呼びます。
  • もう1つの戦略は、下の図の青い四角形に示すように、四角形を回転させて最小面積の四角形を見つけ、その中に輪郭を合わせるだけ*最小外接矩形 * minAreaRectです。

ここに画像の説明を挿入

正の境界長方形boudningRect

関数は比較的単純で、渡されるパラメーターはだけです轮廓点集(单个) Points

rect = cv2.boundingRect(cnt)
(x, y, w, h) = rect

戻り値rect、データ構造はtuple、長方形の左上隅の座標(x, y)、および長方形の幅とw高さh

長方形の領域の情報を順番に印刷します。

for cidx,cnt in enumerate(contours):
    (x, y, w, h) = cv2.boundingRect(cnt)
    print('RECT: x={}, y={}, w={}, h={}'.format(x, y, w, h))

出力結果:

RECT: x=92, y=378, w=94, h=64
RECT: x=381, y=328, w=69, h=102
RECT: x=234, y=265, w=86, h=70
RECT: x=53, y=260, w=61, h=95
RECT: x=420, y=184, w=49, h=66
RECT: x=65, y=124, w=48, h=83
RECT: x=281, y=71, w=70, h=108

キャンバス上での描画はより直感的です。具体的なコードは次のとおりです。

import numpy as np
import cv2

# 读入黑背景下的彩色手写数字
img = cv2.imread("color_number_handwriting.png")
# 转换为gray灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 寻找轮廓
contours, hier = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 声明画布 拷贝自img
canvas = np.copy(img)

for cidx,cnt in enumerate(contours):
    (x, y, w, h) = cv2.boundingRect(cnt)
    print('RECT: x={}, y={}, w={}, h={}'.format(x, y, w, h))
    # 原图绘制圆形
    cv2.rectangle(canvas, pt1=(x, y), pt2=(x+w, y+h),color=(255, 255, 255), thickness=3)
    # 截取ROI图像
    cv2.imwrite("number_boudingrect_cidx_{}.png".format(cidx), img[y:y+h, x:x+w])

cv2.imwrite("number_boundingrect_canvas.png", canvas)

元の画像:
ここに画像の説明を挿入
描画結果:
ここに画像の説明を挿入

ROI画像のインターセプトの操作は比較的簡単img[y:y+h, x:x+w]です。

# 截取ROI图像
cv2.imwrite("number_boudingrect_cidx_{}.png".format(cidx), img[y:y+h, x:x+w])

このようにして、1つの数値の別の画像を傍受しました。
ここに画像の説明を挿入

最小囲み長方形minAreaRect

minAreaRect関数は、最小面積の長方形取得するために使用されます

minAreaRect = cv2.minAreaRect(cnt)

minAreaRectを出力して、返されたデータ構造を確認してみましょう。

((133.10528564453125, 404.7727966308594), (100.10702514648438, 57.51853942871094), -49.184913635253906)

データ構造分析

((cx, cy), (width, height), theta)
  • cx 長方形の中心xの中心点のx座標
  • cy 長方形の中心yの中心点のy座標
  • width 長方形の幅
  • height 長方形の高さ
  • theta 回転角度、角度(ラジアンではない)

注:上記の値はすべて小数であり、画像のインデックス作成や長方形の描画に直接使用することはできません。

詳細は図をご覧ください

ここに画像の説明を挿入

画像ソースpython opencv minAreaRectは最小の外接長方形を生成します

:回転角度θは、水平軸(x軸)と、反時計回りに回転した長方形の最初の辺との間の角度です。そして、この辺の長さが幅、反対側の長さが高さです。つまり、ここでは、幅と高さは長さで定義されていません。

opencvでは、座標系の原点は左上隅にあり、x軸に対して反時計回りの回転角度は負、時計回りの回転角度は正です。

直感のために、このような値を直接割り当てることができます

((cx, cy), (width, height), theta) = cv2.minAreaRect(cnt)

いくつかの完全なデモ例:

for cidx,cnt in enumerate(contours):
    ((cx, cy), (width, height), theta) = cv2.minAreaRect(cnt)
    print('center: cx=%.3f, cy=%.3f, width=%.3f, height=%.3f, roate_angle=%.3f'%(cx, cy, width, height, theta))

出力結果:

center: cx=133.105, cy=404.773, width=100.107, height=57.519, roate_angle=-49.185 
center: cx=415.190, cy=378.853, width=66.508, height=100.537, roate_angle=-1.710  
center: cx=278.323, cy=296.089, width=71.608, height=78.065, roate_angle=-78.440  
center: cx=83.000, cy=307.000, width=60.000, height=94.000, roate_angle=0.000     
center: cx=448.346, cy=213.731, width=47.068, height=64.718, roate_angle=-11.310  
center: cx=89.642, cy=164.695, width=17.204, height=88.566, roate_angle=-25.427   
center: cx=330.578, cy=123.387, width=92.325, height=72.089, roate_angle=-66.666 

完全なコード表示:

import numpy as np
import cv2

# 读入黑背景下的彩色手写数字
img = cv2.imread("color_number_handwriting.png")
# 转换为gray灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 寻找轮廓
contours, hier = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 声明画布 拷贝自img
canvas = np.copy(img)

for cidx,cnt in enumerate(contours):
    minAreaRect = cv2.minAreaRect(cnt)
    # 转换为整数点集坐标
    rectCnt = np.int64(cv2.boxPoints(minAreaRect))
    # 绘制多边形
    cv2.polylines(img=canvas, pts=[rectCnt], isClosed=True, color=(0,0,255), thickness=3)

cv2.imwrite("number_minarearect_canvas.png", canvas)

ここに画像の説明を挿入

最小の外接長方形領域を抽出します

minAreaRect関数(cx, cy)から返されたデータ構造に従って、長方形の中心を元の画像の回転の中心点として使用し、回転角度をtheta次のように設定できます。

# 声明旋转矩阵
rotateMatrix = cv2.getRotationMatrix2D((cx, cy), theta, 1.0)
# 获取旋转后的图像
rotatedImg = cv2.warpAffine(img, rotateMatrix, (img.shape[1], img.shape[0]))

具体的なコードは次のとおりです。

'''
    利用minAreaRect绘制最小面积矩形并绘制
'''
import numpy as np
import cv2

# 读入黑背景下的彩色手写数字
img = cv2.imread("color_number_handwriting.png")
# 转换为gray灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 寻找轮廓
contours, hier = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for cidx,cnt in enumerate(contours):
    minAreaRect = cv2.minAreaRect(cnt)
    # 转换为整数点集坐标
    # rectCnt = np.int64(cv2.boxPoints(minAreaRect))
    ((cx, cy), (w, h), theta) = minAreaRect

    cx = int(cx)
    cy = int(cy)
    w = int(w)
    h = int(h)
    # 获取旋转矩阵
    rotateMatrix = cv2.getRotationMatrix2D((cx, cy), theta, 1.0)
    rotatedImg = cv2.warpAffine(img, rotateMatrix, (img.shape[1], img.shape[0]))
    pt1 = (int(cx - w/2), int(cy - h/2))
    pt2 = (int(cx + w/2), int(cy + h/2))
    # 原图绘制矩形区域
    cv2.rectangle(rotatedImg, pt1=pt1, pt2=pt2,color=(255, 255, 255), thickness=3)
    # 绘制中心点
    cv2.circle(rotatedImg, (cx, cy), 5, color=(255, 0, 0), thickness=-1)
    cv2.imwrite("minarearect_cidx_{}.png".format(cidx), rotatedImg)

ここに画像の説明を挿入

均一サイズへのデジタルサンプル画像変換

数字を含む外接長方形をインターセプトしましたが、それらの形状は異なります。(手動回転が必要な場合があります)

ここに画像の説明を挿入

ニューラルネットワークで必要なサンプル画像を作成する場合は、均一なサイズにスケーリングする必要があります。

次に、統一された画像 15*25に変換され、バイナリイメージに変換されます。
ここに画像の説明を挿入
具体的なコードは次のとおりです。

import numpy as np
import cv2
from glob import glob

img_paths = glob('./数字图像处理/*.png')

# 新的维度为10×20
new_dimension = (15, 25)

for img_path in img_paths:
    # 读入灰度图
    img = cv2.imread(img_path,cv2.IMREAD_GRAYSCALE)
    img_name = img_path.split('/')[-1]
    # 缩放
    resized = cv2.resize(img, new_dimension)
    # 二值化图片
    ret,thresh = cv2.threshold(resized,10,255,0)

    cv2.imwrite('./number/'+img_name,thresh)

リソースポータル

  1. [ 入札プログラムの類人になる ]パブリックアカウントに注意してください
  2. 背景に返信[ 入札プログラム猿う [パブリックアカウントに]Pythonデータ】【2020秋募集】対応するサプライズがもらえる!

「❤️みんなありがとう」

  1. より多くの人々がこのコンテンツを見ることができるように、それをサポートしたい(あなたそれを気に入らない場合、それはすべてフーリガンです-_-
  2. メッセージエリアで私とあなたの考えを共有することを歓迎し、メッセージエリアであなたの考えのプロセスを記録することを歓迎します。

おすすめ

転載: blog.csdn.net/ywsydwsbn/article/details/108441372