Upgrade to Pro — share decks privately, control downloads, hide ads and more …

画像処理ライブラリOpenCVの使い方0910

OHNO
September 10, 2020

 画像処理ライブラリOpenCVの使い方0910

OHNO

September 10, 2020
Tweet

More Decks by OHNO

Other Decks in Programming

Transcript

  1. 画像処理ライブラリ
    OpenCVの使い方
    新潟県工業技術総合研究所
    中越技術支援センター
    大野 宏
    AIイノベーションハブ講演会
    2020/9/10

    View Slide

  2. 新潟県工業技術総合研究所の概要
    ・大正3年に設立された県立の工業の試験研究機関
    ・主な業務内容は、依頼試験、機器貸出、技術相談、
    情報提供、研究開発
    ・下越、県央、中越、上越、素材、研究開発の各センター
    詳細は「工技総研」で検索
    http://www.iri.pref.niigata.jp

    View Slide

  3. 新潟県のAI・IoT活用支援事業
    ・平成28年度から開始
    ・県内企業へのAI・IoTの啓蒙普及のための講演会や講
    習会の開催
    ・実証事業や導入補助金(新潟県産業労働部)
    ・県内企業との共同研究やAI・IoT相談窓口の設置
    (工業技術総合研究所)

    View Slide

  4. 県の共同研究事業
    ・ウエノテックス(株)
    「廃棄物選別ロボットの開発」 2016~2017
    「タイヤ用検査装置の開発」 2016~2017
    ・(株)ミツワ
    「野菜色彩形状選別機の開発」 2018~2019
    ・THK新潟(株)
    「AIを活用した金属製品の外観認識の自動化」2020~

    View Slide

  5. 山積み部品のピッキングシステム
    ・部品の距離画像からディープラーニングでどの部品から先
    にピッキングするか推定し、画像処理で位置と傾きを計算

    View Slide

  6. 講演の背景
    ・ディープラーニングで画像分類、特に外観を検査するた
    めには、綺麗な画像を撮ることが大事
    照明、カメラ、レンズ
    ・前処理や後処理に画像処理が必要
    無料の画像処理ライブラリOpenCV

    View Slide

  7. 発表の概要
    ・カメラやレンズの基礎
    白黒カメラとカラーカメラ
    レンズの役割
    ・OpenCVの基礎
    画像の変換、エッジ、フィルタ、2値化とラベリング
    ・OpenCVによる傷の検査
    ・OpenCVかディープラーニングか
    ・Pythonによる工業用カメラの制御

    View Slide

  8. 白黒とカラー1
    白黒カメラ カラーカメラ
    カラーカメラは模式的に、RGB3枚の受光素子があるよう
    に書かれることが多いが、実際は次ページのように1枚

    View Slide

  9. 白黒とカラー2
    白黒カメラ カラーカメラ
    これで1画素
    ・カラーカメラを白黒で使うと、640×480の画像を得るには
    1,280×960画素のカメラが必要
    ・同じ画素数なら白黒カメラの方が単位時間当たりに撮像
    できるフレーム数が多く、パソコンへの転送も速い

    View Slide

  10. シャッタースピード
    ・移動物体を撮像する場合は、シャッタースピード(露光時
    間)が速くないとぶれてしまう。
    ・シャッタースピードが速い場合は、十分な光量を確保す
    る必要がある(明るい照明やレンズの絞りを開く)。

    View Slide

  11. 視野1
    視野:撮像範囲のこと、焦点距離が短いと広範囲を撮像
    可能 映像素子
    映像素子
    画角
    画角
    焦点距離
    焦点距離

    View Slide

  12. 視野2
    大きく撮像したい場合は焦点距離の長いレンズを選択
    映像素子
    映像素子
    画角
    画角
    焦点距離
    焦点距離

    View Slide

  13. ひずみ
    焦点距離が短いと広範囲を撮像可能であるが、周辺が
    ひずむ → 基準パターンを使ってひずみを補正

    View Slide

  14. OpenCV
    ・無料の画像処理用ライブラリ
    ・マルチプラットフォーム
    Windows、Linux、Mac、iOS、Android
    C、C++、Python、Java
    ・Intel社が開発して公開→Willow Garage社が開発・管理
    ・機械学習(ディープラーニングを含む)サンプルも多数
    ・matplotlib や Pillow より高機能

    View Slide

  15. Pythonでよく使われる画像ライブラリ
    ・matplotlibグラフ作成ライブラリ
    学習回数―認識率の
    グラフや画像の表示
    ・Pillow
    画像の回転や拡大縮小など基本的な処理

    View Slide

  16. その他の画像処理ソフト
    ・ImageJ (無料)
    メニュー形式で操作
    化学・生物系の研究者が主に利用
    ・HALCON (有料)
    OpnCVと同様にプログラム形式
    独特のスクリプト言語で記述
    ドイツの会社が開発・販売し日本はリンクスが代理店
    ・PLCメーカの画像処理ユニット

    View Slide

  17. OpenCVの基本的な機能
    ・画像の読み込みと表示
    ・画像の拡大と縮小
    ・画像の回転
    ・図形の描画
    ・フィルタ処理
    ・ラベリング
    ・2値化

    View Slide

  18. OpenCVのインストール方法
    ・ターミナルを開いて
    pip install opencv-python
    ・確認
    ターミナルでPythonを起動し
    $python [Enter]
    下記の通りに入力して何も表示されなければOK
    >>import cv2 [Enter]
    >>
    ・Numpyもインストールしておくとよい

    View Slide

  19. 画像の読み込みと表示
    #カラー
    img1=cv2.imread("lena.jpg",1)
    cv2.imshow ( "img1", img1 )
    cv2.waitKey(1000) #1秒間待機
    #白黒
    img1=cv2.imread("lena.jpg",0)
    cv2.imshow ( "img2", img2 )
    cv2.imwrite(“img.png” , img2) #画像の保存
    cv2.waitKey(0) #Enterキーで終了
    Test0.py

    View Slide

  20. カメラ画像の表示
    カメラがパソコンについている場合
    cap=cv2.VideoCapture(0)
    while True:
    ret,img1=cap.read()
    cv2.imshow('img1',img1)
    key=cv2.waitKey(1)
    if key==ord('q' ):
    break
    cap.release()
    cv2.destroyAllWindows()
    Test1.py

    View Slide

  21. 画像の拡大と縮小
    img1=cv2.imread("building.jpg",1)
    height = img1.shape[0]
    width = img1.shape[1]
    #縮小
    img2=cv2.resize(img1,(int(width*0.5), int(height*(0.5)))
    cv2.imshow( "img2", img2 )
    cv2.waitKey(1000)
    Test3.py

    View Slide

  22. 画像の反転、回転1
    img1=cv2.imread("building.jpg",1)
    img2=cv2.flip(img1,0) #上下反転 0
    cv2.imshow ( "img2", img2 )
    cv2.waitKey(1000)
    img2=cv2.flip(img1,1) #左右反転 >0
    img2=cv2.flip(img1,-1) #左右反転 <0
    img2=cv2.rotate(img1, cv2.ROTATE_90_CLOCKWISE)
    img2=cv2.rotate(img1, cv2.ROTATE_180)
    img2=cv2.rotate(img1,cv2.ROTATE_90_COUNTERCLOCKWISE)
    Test4.py

    View Slide

  23. 画像の回転2
    img1=cv2.imread("building.jpg",1)
    height = img1.shape[0]
    width = img1.shape[1]
    center = (int(width/2), int(height/2))
    angle = 45.0
    scale = 1.0
    trans = cv2.getRotationMatrix2D(center, angle , scale)
    img2 = cv2.warpAffine(img1, trans, (width,height))
    cv2.imshow ( "img2", img2 )
    cv2.waitKey(1000)
    Test5.py

    View Slide

  24. 画像の反転と回転の結果
    元画像 左右反転
    上下反転(180度回転) 45度回転

    View Slide

  25. 画像の切り出し
    img1=cv2.imread("lena.jpg")
    img2=img1[150:400, 100:450]
    cv2.imshow ( "img2", img2 )
    cv2.waitKey(1000) (100, 150)
    (450, 400)
    Test6.py

    View Slide

  26. 四角形、線、円の描画
    img1=cv2.imread("building.jpg",1)
    cv2.rectangle(img1, (200, 200), (500, 500), (255, 0, 0),
    thickness=2, lineType=cv2.LINE_4)
    cv2.line(img1, (100, 100), (600, 100), (0, 255, 0),
    thickness=2, lineType=cv2.LINE_4)
    cv2.circle(img1, (440,400), 100, (0,0,255), thickness=2,
    lineType=cv2.LINE_4, shift=0)
    cv2.imshow ( "img", img1 )
    cv2.waitKey(1000)
    Test7.py

    View Slide

  27. フィルタ処理
    -1 0 1
    -2 0 2
    -1 0 1
    一定の大きさのカーネル(オペレータ)で積和演算(畳み
    込み計算)を行う。全画素に対してこの計算を実施。

    View Slide

  28. フィルタ処理(平均値)
    img1=cv2.imread("lena.jpg")
    #平均値フィルタ
    img2=cv2.blur(img1,(3,3))
    cv2.imshow ( "img2", img2 )
    cv2.waitKey(1000)
    1/9 1/9 1/9
    1/9 1/9 1/9
    1/9 1/9 1/9
    Test9.py

    View Slide

  29. フィルタ処理(Sobel)
    img1=cv2.imread("building.jpg",0)
    img3=cv2.Sobel(img1,cv2.CV_32F,1,0)
    img3=cv2.convertScaleAbs(img3)
    cv2.imshow ( "img1", img1 )
    cv2.imshow ( "img3", img3 )
    cv2.imwrite("building1.png",img3)
    cv2.waitKey(1000)
    -1 0 1
    -2 0 2
    -1 0 1
    Test10.py

    View Slide

  30. フィルタ処理(Sobel)
    img1=cv2.imread("building.jpg",0)
    img2=cv2.Sobel(img1,cv2.CV_32F,0,1)
    img2=cv2.convertScaleAbs(img2)
    cv2.imshow ( "img1", img1 )
    cv2.imshow ( "img2", img2 )
    cv2.waitKey(1000)
    img1=cv2.imread("building1.png",0)
    img3=img2|img3
    cv2.imshow ( "img3", img3 )
    cv2.waitKey(1000) 縦方向の変化を強調
    -1 -2 -1
    0 0 0
    1 2 1
    Test11.py

    View Slide

  31. フィルタ処理(Sobel)の結果

    View Slide

  32. フィルタ処理(Canny)
    輪郭線を綺麗に抽出するフィルター
    img1=cv2.imread("building.jpg",0)
    img2=cv2.Canny(img1,100,200)
    cv2.imshow ( "img1", img1 )
    cv2.imshow ( "img2", img2 )
    cv2.waitKey(1000)
    Test12.py

    View Slide

  33. 2値化とラベリング1
    2値化:グレイスケールの画像を適当な値で0と1に分ける
    ラベリング:1の塊ごとに番号をつける
    元画像 ラベルごとに色付け

    View Slide

  34. 2値化とラベリング2
    img1=cv2.imread("pic1.png”,1)
    img2=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
    #2値化
    ret,img3=cv2.threshold(img2,100,255,cv2.THRESH_BINARY)
    #ラベリング
    n,label=cv2.connectedComponents(img3)
    height = img3.shape[0]
    width = img3.shape[1]
    str1='height:'+str(height)+' width:'+str(width)
    print(str1)
    cv2.imshow ( "img3", img3 )
    Test13.py

    View Slide

  35. ラベルの色付け
    colors=[]
    colors.append([0,0,0])
    colors.append([255,0,0])
    colors.append([0,255,0])
    colors.append([0,0,255])
    colors.append([0,255,255])
    for y in range(0,height):
    for x in range(0,width):
    if 0img1[y,x]=colors[label[y,x]]
    else:
    img1[y,x]=[0,0,0]
    cv2.imshow ( "img1", img1 )
    cv2.waitKey(0)
    Test13.py
    数字の場合
    OpenCVで1文字ずつ切り出
    しディープラーニングで認識

    View Slide

  36. 傷の検査
    傷を抽出する
    地の明るさが不均一

    View Slide

  37. 2値化
    img1=cv2.imread("kizu.png",0)
    cv2.imshow ( "img1", img1 )
    #2値化
    ret,img2=cv2.threshold(img1,120,255,1)
    cv2.imshow ( "img2", img2 )
    cv2.waitKey(1000)
    ・2値化の閾値を変えてみよう
    Test14.py

    View Slide

  38. 地の明るさ
    img1=cv2.imread("kizu.png",0)
    img2=np.zeros([256,400]).astype('uint8')
    for x in range(0,400):
    dat=0
    for y in range(80,90):
    dat=dat+img1[y,x]
    dat=int(0.1*dat)
    cv2.line(img2,(x,0),(x,dat),(255,25,255))
    cv2.imshow ( "img1", img1 )
    cv2.imshow ( "img2", img2 )
    cv2.waitKey(0)
    Test15.py
    地の明るさが不均一

    View Slide

  39. 動的2値化処理
    地の明るさを均一に
    img1=cv2.imread("kizu.png",0)
    #平均値フィルタ
    img2=cv2.blur(img1,(32,32))
    img3=img1-img2+127
    cv2.imshow ( "img1", img1 )
    cv2.imshow ( "img2", img2 )
    cv2.imshow ( "img3", img3 )
    cv2.imwrite ( “kizu1.png", img3 )
    cv2.waitKey(0)
    Test16.py

    View Slide

  40. 地の明るさ(改良後)
    img1=cv2.imread("kizu1.png",0)
    img2=np.zeros([256,400]).astype('uint8')
    for x in range(0,400):
    dat=0
    for y in range(80,90):
    dat=dat+img1[y,x]
    dat=int(0.1*dat)
    cv2.line(img2,(x,0),(x,dat),(255,25,255))
    cv2.imshow ( "img2", img2 )
    cv2.waitKey(0)
    地の明るさが均一に
    Test17.py

    View Slide

  41. 動的2値化で不良検出 1/2
    img1=cv2.imread("kizu1.png",0)
    #2値化
    ret,img2=cv2.threshold(img1,98,255,1)
    #エレメントの設定
    element8=np.array([[1,1,1],[1,1,1],[1,1,1]],np.uint8)
    #モーフィング
    img3=cv2.morphologyEx(img2,cv2.MORPH_CLOSE,element8)
    cv2.imshow ( "img3", img3 )
    cv2.waitKey(0)
    color = cv2.cvtColor(img3, cv2.COLOR_GRAY2BGR)
    #ラベリング
    label=cv2.connectedComponentsWithStats(img3)
    Test18.py

    View Slide

  42. 動的2値化で不良検出 2/2
    n = label[0] - 1
    data = np.delete(label[2], 0, 0)
    center=np.delete(label[3], 0, 0)
    for i in range(n):
    if(data[i][4]>30):
    str1=“n:”+str(data[i][4])+“ x:”+str(int(center[i][0]))+“
    y:"+str(int(center[i][1]))
    print(str1)
    x0 = data[i][0]-2
    y0 = data[i][1]-2
    x1 = data[i][0] + data[i][2]+2
    y1 = data[i][1] + data[i][3]+2
    cv2.rectangle(color, (x0, y0), (x1, y1), (0, 0, 255))
    cv2.imshow ( "color", color )

    View Slide

  43. 検出結果

    View Slide

  44. 従来の画像処理かDeep Learningか
    ・2値化、ラベリング、大きい塊を傷と認識
    → 引っ掻き傷は2値化すると線が途切れる
    ・傷の画像を集め、画像処理(大きさ、濃淡、傾き)で数を
    増し、ディープラーニングで判別
    現画像 2値画像
    直線なら傷
    途切れるとノイズ?

    View Slide

  45. 前処理での利用例
    煎餅の良・不良の判別をYOLOで行う場合、学習データとし
    てアノテーションが必要 → OpenCVを使うと作業が楽
    良品
    不良品(欠けや割れ)

    View Slide

  46. 2値化とラベリングで領域検出
    ・2値化とラベリングして煎餅の領域を検出する

    View Slide

  47. 良・不良のラベル付け
    ・面積で良・不良を判別してラベルを付ける
    良品
    不良品 良品

    View Slide

  48. 目視で修正
    ・誤った半別を目視で修正し、データ作成完了
    良品
    不良品

    View Slide

  49. 画像分類をするためには
    ・製造業で画像分類や傷を検査するためには、多くの高
    解像度の画像が必要
    ・PythonではUSBカメラの画像の取得は容易であるが、高
    解像度の工業用カメラは・・・
    ・メーカが提供するライブラリは、C、C#、C++
    ・画像取り込みはC、画像分類はPython
    → 同じ言語で画像取り込みから分類まで出来るとよい
    露光時間、フレームレート等を制御可能

    View Slide

  50. Basler 社のカメラ
    https://www.baslerweb.com/jp/products/software/basler-pylon-
    camera-software-suite/pylon-open-source-projects/

    View Slide

  51. Pythonライブラリ
    https://github.com/basler/pypylon

    View Slide

  52. Pythonプログラム1/3
    from pypylon import pylon
    from pypylon import genicam
    import sys
    import cv2
    import numpy as np
    width = 2044
    height = 1536
    img1 = np.zeros((height, width, 1), np.uint8)
    countOfImagesToGrab = 10
    exitCode = 0
    try:
    camera =pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
    camera.Open()
    print("Using device ", camera.GetDeviceInfo().GetModelName())
    new_width = camera.Width.GetValue() - camera.Width.GetInc()

    View Slide

  53. Pythonプログラム2/3
    if new_width >= camera.Width.GetMin():
    camera.Width.SetValue(new_width)
    camera.MaxNumBuffer = 5
    while True:
    camera.StartGrabbingMax(1)
    while camera.IsGrabbing():
    grabResult = camera.RetrieveResult(5000,
    pylon.TimeoutHandling_ThrowException)
    if grabResult.GrabSucceeded():
    img = grabResult.Array
    cv2.imshow("img",img)
    key=cv2.waitKey(1)
    else:
    print("Error: ", grabResult.ErrorCode, grabResult.ErrorDescription)
    if key=='q’:
    break
    grabResult.Release()

    View Slide

  54. Pythonプログラム3/3
    camera.Close()
    except genicam.GenericException as e:
    # Error handling.
    print("An exception occurred.")
    print(e.GetDescription())
    exitCode = 1
    sys.exit(exitCode)

    View Slide

  55. 参考図書
    ・Python、C++
    ・各アルゴリズムがどのよう
    な計算をしているかも記述
    ・ネットで検索すると参考にな
    るもの多数あり

    View Slide

  56. 講演会の案内
    ・ディープラーニングの講演会を10月9日に開催
    ・講師は中部大学の山下准教授(今年で5回目)
    最新の技術動向に詳しく、オリジナルの研究でも有名
    ・申し込みを受付中(ただし県内の方に限る)
    ・http://www.iri.pref.niigata.jp/news/R2/2new06.html

    View Slide