新着情報

1-3. 静止画像のGUI処理システム

Fig.1 は静止画像のGUI処理システムを立ち上げ、「顔と目の認識」ボタンをクリックした時の結果を表示している。

ここで示す静止画像のGUI処理システムは(2)のプロトタイプGUI画像処理システムを拡張して、14種類の異なる処理ボタンを配置した静止画像のGUI処理システムである。これを実現するサンプルプログラムImageProcessingGUIsystem.pyを以下に示す。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Mar 12 10:44:33 2019

@author: PBK-****
"""

from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
from matplotlib import pyplot as plt
import sys
import os
import os.path
import numpy as np
import cv2
from PIL import Image, ImageTk, ImageFilter
import time


class App(Frame):
    def __init__(self,master=None):
        #フレーム
        Frame.__init__(self, master)
        self.master.title('画像処理システム')
        self.master.minsize(1000,400)
#        self.filename=None

        #メニューバー
        self.menu_bar = Menu(self.master)
        self.master.config(menu=self.menu_bar)
        
        self.menu_file = Menu(self.menu_bar,tearoff = False)
        self.menu_edit = Menu(self.menu_bar,tearoff = False)
        self.menu_heikatsu = Menu(self.menu_edit,tearoff = False)
        self.menu_hanten = Menu(self.menu_edit,tearoff = False)
        self.menu_bunkatsu = Menu(self.menu_edit,tearoff = False)
        
        self.menu_bar.add_cascade(label='ファイル(F)', menu=self.menu_file,  underline=5)
        self.menu_file.add_command(label='開く­', command=self.open, underline=3, accelerator = 'Ctrl-O')
        self.menu_file.add_command(label='保存', command=self.save, underline=5, accelerator = 'Ctrl-S')
        self.menu_file.add_separator()
        self.menu_file.add_command(label='終了', command=self.quit, underline=5, accelerator = 'Ctrl-Q')


        self.menu_bar.add_cascade(label='編集(E)', menu=self.menu_edit,  underline=5)
        self.menu_edit.add_command(label='二値化', command=self.binarization)
        self.menu_edit.add_cascade(label='平滑化', command=self.quit,menu=self.menu_heikatsu)
        self.menu_heikatsu.add_command(label='ガウシアンフィルター', command=self.gaussianfilter)
        self.menu_heikatsu.add_command(label='メディアンフィルター', command=self.medianfilter)
        self.menu_edit.add_command(label='濃淡化', command=self.grayimage)
        self.menu_edit.add_command(label='ヒストグラム計算', command=self.histgram)
        self.menu_edit.add_command(label='回転', command=self.rotation)
        self.menu_edit.add_command(label='エッジ検出', command=self.edge)
        self.menu_edit.add_cascade(label="反転", command=self.quit,menu=self.menu_hanten)
        self.menu_hanten.add_command(label='上下反転', command=self.upsidedown)
        self.menu_hanten.add_command(label='左右反転', command=self.mirrorimage)
        self.menu_edit.add_command(label='色調反転', command=self.reversecolor)
        self.menu_edit.add_command(label='顔と目の認識', command=self.face_eye)


        self.menu_edit.add_command(label='RGB色分解', command=self.colordecomposition)

        self.menu_edit.add_cascade(label='領域分割', command=self.quit,menu=self.menu_bunkatsu)
        self.menu_bunkatsu.add_command(label='Watershed法', command=self.watershed)
        self.menu_bunkatsu.add_command(label='平均値シフト法', command=self.meanshift)
        self.menu_edit.add_command(label='HSV色空間変換', command=self.hsvcolorspace)

        self.image1 = PhotoImage()
        self.image2 = PhotoImage()

        #ラベル1
        self.la = Label(self,text='target image',image=self.image1,bg="#44aaaa",
                                width=400, height=400)

        self.la.pack(side=LEFT,padx=50, pady=90)

        #ラベル2
        self.la2 = Label(self,text='processed image',image=self.image2, bg="#44aaaa",
                                 width=400, height=400)

        self.la2.pack(side=LEFT,padx=10, pady=90)
        
        #ボタン
        self.button_0 = Button(self,text='対象画像選択',command=self.open,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_1 = Button(self,text='2値化',command=self.binarization,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_2 = Button(self,text='エッジ検出',command=self.edge,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_3 = Button(self,text='濃淡画像',command=self.grayimage,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_4 = Button(self,text='色調反転',command=self.reversecolor,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_5 = Button(self,text='平滑化(Gauss)',command=self.gaussianfilter,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_6 = Button(self,text='平滑化(中央値)',command=self.medianfilter,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_7 = Button(self,text='ヒストグラム',command=self.histgram,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_8 = Button(self,text='上下反転',command=self.upsidedown,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_9 = Button(self,text='左右反転',command=self.mirrorimage,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_10 = Button(self,text='顔と目の認識',command=self.face_eye,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_11 = Button(self,text='RGB色分解',command=self.colordecomposition,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_12 = Button(self,text='HSV色空間',command=self.hsvcolorspace,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)
        self.button_13 = Button(self,text="終了",command=self.quit,width=10).pack(side=TOP,padx=10, pady=10,anchor=W)



    #終了
    def quit(self):
       if messagebox.askokcancel('Confirm Close', 'Are you sure you want to close?'):
         self.master.destroy()

    #開く
    def open(self):
          global filename
          global size
          size=400,400
          filename = filedialog.askopenfilename()
          if filename != "":
            im = Image.open(filename)
            im.thumbnail(size, Image.ANTIALIAS)
          if im.mode == '1': # 1 bit 白黒 bitmap image
            self.image1 = ImageTk.BitmapImage(im, foreground="white")
          else:              # color photo image
            self.image1 = ImageTk.PhotoImage(im)
          self.la.config(text='Target Image',image=self.image1,
                         width=self.image1.width(), height=self.image1.height(),compound='top')


    #保存
    def save(self):
        global filename
        global filename2
        currentdir=os.path.dirname(__file__)
        filename =  filedialog.asksaveasfilename(initialdir = currentdir,title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
#        cv2.imwrite('result.jpg',filename2)
        cv2.imwrite(filename,filename2)
#        print(os.path.basename(filename))        

    def callback(self):
        print( "Entererd from",self.x,self.y)

    #二値化
    def binarization(self):
          global filename
          global filename2
          global size

          filename2 = cv2.imread(filename,0);
          filename2 = cv2.adaptiveThreshold(filename2,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
          cv2.imwrite('binary.jpg',filename2)
          im2 = Image.open('binary.jpg')
          im2.thumbnail(size,Image.ANTIALIAS)

          self.image2 = ImageTk.PhotoImage(im2)
                            
          self.la2.config(text='Binary Image',image=self.image2,
                         width=self.image2.width(), height=self.image2.height(),compound='top')                                            



        
    #平滑化1
    def gaussianfilter(self):
          global filename
          global filename2
          global size

          image2 = cv2.imread(filename)
        # ガウシアンフィルター処理
          filename2 = cv2.GaussianBlur(image2,(5,5),0)
          cv2.imwrite('smoothgaussianf.jpg',filename2)
          im2 = Image.open('smoothgaussianf.jpg')
          im2.thumbnail(size,Image.ANTIALIAS)
          self.image2 = ImageTk.PhotoImage(im2)
          self.la.config(image=self.image1,
                         width=self.image1.width(), height=self.image1.height())                                
          self.la2.config(text='Smoothed by GaussianF',image=self.image2,
                         width=self.image2.width(), height=self.image2.height())         

    #平滑化2
    def medianfilter(self):
        global filename
        global filename2
        global size
        
        image = cv2.imread(filename)
        # メディアンフィルター処理
        filename2 = cv2.medianBlur(image,9) #kernel size should be odd number
        cv2.imwrite('smoothmedianf.jpg',filename2)
        im2 = Image.open('smoothmedianf.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='Smoothed by MedianF',image=self.image2,
                         width=self.image2.width(), height=self.image2.height(),compound='top')      


    #モノクロ処理
    def grayimage(self):
        global filename
        global filename2
        global size
        filename2 = cv2.imread(filename,0)
        cv2.imwrite('Gray.jpg',filename2)
        im2 = Image.open('Gray.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)

        self.image2 = ImageTk.PhotoImage(im2)
                       
        self.la2.config(text='Gray Image',image=self.image2,
                         width=self.image2.width(), height=self.image2.height(),compound='top')      
        

    #ヒストグラム計算
    def histgram(self):
        global filename
        im = cv2.imread(filename)
 
        graph = plt.figure()
 
        graph.add_subplot(311)
        plt.hist(im[:,:,0].ravel(), 256, range=(0, 255), fc='b')
        plt.xlim(0,255)
 
        graph.add_subplot(312)
        plt.hist(im[:,:,1].ravel(), 256, range=(0, 255), fc='g')
        plt.xlim(0,255)
 
        graph.add_subplot(313)
        plt.hist(im[:,:,2].ravel(), 256, range=(0, 255), fc='r')
        plt.xlim(0,255)
 
        #plt.show()

        plt.savefig('Histgrams.png',figsize=(6,5),dpi=150)        
        im2=Image.open('Histgrams.png')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='BGR Histograms',image=self.image2,
                        width=self.image2.width(),height=self.image2.height(),compound='top')

        

    #回転
    def rotation(self):
        global filename
        global filename2
        global size
        im = cv2.imread(filename)
        h,w,ch = im.shape
        M = cv2.getRotationMatrix2D((w/2,h/2),60,1)
        filename2 = cv2.warpAffine(im,M,(w,h))
        cv2.imwrite('Rotation.jpg',filename2)
        im2=Image.open('Rotation.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='Image Rotated by 60゜',image=self.image2,
                        width=self.image2.width(),height=self.image2.height(),compound='top')

    #エッジ検出
    def edge(self):
        global filename
        global filename2
        global size
        gray = cv2.imread(filename,0)
        # cannyアルゴリズムでエッジ抽出
        filename2 = cv2.Canny(gray,100,200)
        cv2.imwrite('EdgedByCanny.jpg',filename2)
        im2=Image.open('EdgedByCanny.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='Edge by CannyM',image=self.image2,
                        width=self.image2.width(),height=self.image2.height(),compound='top')        

    #上下反転
    def upsidedown(self):
        global filename
        global filename2
        img=cv2.imread(filename)
        filename2=img.copy()
        filename2=cv2.flip(img,0)
        cv2.imwrite('UpDownFlip.jpg', filename2)
        im2=Image.open('UpDownFlip.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='UpsideDown Flipped Image',image=self.image2,
                        width=self.image2.width(),height=self.image2.height(),compound='top')        

    #左右反転        
    def mirrorimage(self):
        global filename
        global filename2
        global size
        img=cv2.imread(filename)
        filename2=img.copy()
        filename2=cv2.flip(img,1)
        cv2.imwrite('LeftRightFlip.jpg', filename2)
        im2 = Image.open('LeftRightFlip.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='LeftRight Flipped Image',image=self.image2,
                        width=self.image2.width(),height=self.image2.height(),compound='top') 

    #色調反転
    def reversecolor(self):
        global filename
        global filename2
        im = cv2.imread(filename)
        filename2 = 255 - im
        cv2.imwrite('ColorReversed.jpg',filename2)
        im2 = Image.open('ColorReversed.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='Color Reversed Image',image=self.image2,
                        width=self.image2.width(),height=self.image2.height(),compound='top') 

    #顔認識
    def face_eye(self):
        global filename
        global filename2
        
        face_cascade_path = './haarcascades/haarcascade_frontalface_default.xml'
        eye_cascade_path = './haarcascades/haarcascade_eye.xml'
        
        face_cascade = cv2.CascadeClassifier(face_cascade_path)
        eye_cascade = cv2.CascadeClassifier(eye_cascade_path)
        
        src = cv2.imread(filename)
        src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(src_gray,1.1,3)

        for x, y, w, h in faces:
            cv2.rectangle(src, (x, y), (x + w, y + h), (0, 255, 255), 2)
            face = src[y: y + h, x: x + w]
            face_gray = src_gray[y: y + h, x: x + w]
            eyes = eye_cascade.detectMultiScale(face_gray)
            for (ex, ey, ew, eh) in eyes:
                cv2.rectangle(face, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
        cv2.imwrite('face-eye_detected.jpg', src)
        im2 = Image.open('face-eye_detected.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='Face Detection',image=self.image2,
                         width=self.image2.width(), height=self.image2.height(),compound='top')  

    #成分抽出
    def colordecomposition(self):
        global filename
        img = plt.imread(filename)
        print (img.shape)
        img_arr = np.asarray(img)
        img_r = img_arr.copy()
        img_r[:,:,(1,2)]=0
        
        img_g = img_arr.copy()
        img_g[:,:,(0,2)]=0
        
        img_b = img_arr.copy()
        img_b[:,:,(0,1)]=0
        
        fig = plt.figure()
        fig.suptitle('Color Components',fontsize = 16) 
        ax1 = fig.add_subplot(131)
        ax1.set_title('Red') 
        plt.imshow(img_r)
        ax2 = fig.add_subplot(132) 
        ax2.set_title('Green') 
        plt.imshow(img_g)
        ax3 = fig.add_subplot(133) 
        ax3.set_title('Blue') 
        plt.imshow(img_b)
        #plt.show()
        plt.savefig('figure.jpeg',figsize=(9,3),dpi=150)
        im2=Image.open('figure.jpeg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='Color Decomposition',image=self.image2,
                        width=self.image2.width(),height=self.image2.height(),compound='top')


    #領域分割1
    def watershed(self): 
        global filename
        global filename2
        filename2 = cv2.imread(filename)
        gray = cv2.cvtColor(filename2,cv2.COLOR_BGR2GRAY)
        th = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1]
        k = np.ones((3,3),np.uint8)
        bg = cv2.dilate(th,k,iterations=3)
        trans = cv2.distanceTransform(bg,cv2.DIST_L2,3)
        fg = cv2.threshold(trans,0.1*trans.max(),255,0)[1]
        fg = np.uint8(fg)
        unknown = cv2.subtract(bg,fg) 
        marker = cv2.connectedComponents(fg)[1] 
        marker = marker + 1 
        marker[unknown == 255] = 0  
        marker = cv2.watershed(filename2,marker) 
        filename2[marker == -1] = [0,255,0] 
        cv2.imwrite("Watershed.jpg",filename2) 
        im2 = Image.open('Watershed.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='Segmentation(Watershed法)',image=self.image2,
                         width=self.image2.width(), height=self.image2.height(),compound='top')   
 
    #領域分割2
    def meanshift(self): 
        global filename
        global filename2
        filename2 = cv2.imread(filename) 
        cv2.pyrMeanShiftFiltering(filename2, 3, 50, filename2, 1) 
        cv2.imwrite('DividedByRegion.jpg',filename2) 
        im2 = Image.open('DividedByRegion.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='Segmentation(平均シフト法)',image=self.image2,
                         width=self.image2.width(), height=self.image2.height(),compound='top')   
 
    #HSV色空間
    def hsvcolorspace(self):
        global filename
        global filename2
        filename2 = cv2.imread(filename)
        filename2 = cv2.cvtColor(filename2, cv2.COLOR_RGB2HSV)
        cv2.imwrite("hsv.jpg",filename2)
        im2 = Image.open('hsv.jpg')
        im2.thumbnail(size,Image.ANTIALIAS)
        self.image2 = ImageTk.PhotoImage(im2)
        self.la2.config(text='Image in HSV Color Space',image=self.image2,
                         width=self.image2.width(), height=self.image2.height(),compound='top')  


if __name__ == '__main__':
     f = App()

コメント投稿フォーム

メールアドレスが公開されることはありません。 が付いている欄は必須項目です