[PYTHON] Try processing images and webcams Part 3 ~ Mosaic processing ~

Introduction

I tried to process images and webcams using Python Part 3

Continuing from the previous time , images (video) using ** OpenCV ** ) I tried processing This time, the process of adding a mosaic to the image and the webcam image!

The item description is as follows

Module, directory structure, etc.

module

Use the same module as last time Install it if you need it!

pip install opencv-python #Required when using OpenCV features(Use with cv2 on python)
pip install numpy         #Extension module for efficient numerical calculation
pip install os            #You can use functions that depend on os

Directory structure

The directory structure is as follows

-- rgb.py
   -- camera_mosaic.py # new
   -- color_process.py
   -- photo_process.py
   -- photo_mosaic.py  # new
   -- rgb.py
   -- img
      -- fruit.jpg

The photo uses fruits as before fruit.jpg

Image mosaic

Shrink the part you want to mosaic and restore it

program

photo_mosaic.py


import cv2
import os

PATH = './img'
FILES = os.listdir(PATH)

OLD_WINDOW_NAME = 'old'
NEW_WINDOW_NAME = 'new'
ratio = 0.1 #Mosaic roughness

# get file name
def get_file_name():
    print('*** All  Pictures ***')
    print(*FILES, sep='\n')
    print('***      End      ***')
    
    while True:
        file_name = input('Which use file name ?: ')
        if file_name in FILES:
            return file_name
        else:
            print('not exist: ' + file_name)

#Mosaic processing
def mosaic(src):
    small = cv2.resize(src, None, fx=ratio, fy=ratio, interpolation=cv2.INTER_NEAREST)
    return cv2.resize(small, src.shape[:2][::-1], interpolation=cv2.INTER_NEAREST)

#Set the mosaic part
def mosaic_area(src, x, y, width, height):
    dst = src.copy()
    dst[y:y + height, x:x + width] = mosaic(dst[y:y + height, x:x + width])
    return dst

if __name__ == '__main__':
    
    old_file_name = get_file_name()
    file_prefixes = old_file_name.rsplit('.', 1)
    new_file_name = file_prefixes[0] + '_mosaic.' + file_prefixes[1]

    #Load the original image
    old_img = cv2.imread(PATH + '/'+ old_file_name)
    
    #Mosaic
    new_img = mosaic_area(old_img, 100, 50, 100, 150)
    
    #Create window
    cv2.namedWindow(OLD_WINDOW_NAME)
    cv2.namedWindow(NEW_WINDOW_NAME)

    #Show in window
    cv2.imshow(OLD_WINDOW_NAME, old_img)
    cv2.imshow(NEW_WINDOW_NAME, new_img)

    #Save to file
    cv2.imwrite(r'img/{}'.format(new_file_name), new_img)

    #End processing
    cv2.waitKey(0)
    cv2.destroyAllWindows()

A little commentary

dst = src.copy()

Copy src (original image) to dst (image to be processed) At first, I coded as follows and had a headache ... dst = src

dst[y:y + height, x:x + width] = mosaic(dst[y:y + height, x:x + width])

Processing to change the range specified by dst to the image sent from the mosaic function Note that x and y are reversed!

small = cv2.resize(src, None, fx=ratio, fy=ratio, interpolation=cv2.INTER_NEAREST)

Resize image with cv2.resize The smaller the ratio, the coarser the mosaic, and the larger the ratio, the finer the mosaic.

INTER_NEAREST is the nearest neighbor interpolation method How to use the nearest pixel as it is

return cv2.resize(small, src.shape[:2][::-1], interpolation=cv2.INTER_NEAREST)

Return to original size Get the shape of the array with src.shape This time it's (150, 100, 3), so it's a 100x3 150-dimensional array. When this is processed, it becomes as follows

src.shape => (150, 100, 3)
src.shape[:2] => (150, 100)
src.shape[:2][::-1] => (100, 150) 

This seems to return to the original size

Output result

Command line gazou3.PNG

Image mosaic When ratio = 0.1 fruit_mosaic_01.jpg

When ratio = 0.9 fruit_mosaic_06.jpg

Webcam mosaic

I tried to put the whole mosaic in the video using the webcam To mosaic the whole thing, do the mosaic processing without going through the mosaic_area function.

program

camera_mosaic.py


import cv2

cap = cv2.VideoCapture(0)
ratio = 0.1

def mosaic(src):
    small = cv2.resize(src, None, fx=ratio, fy=ratio, interpolation=cv2.INTER_NEAREST)
    return cv2.resize(small, src.shape[:2][::-1], interpolation=cv2.INTER_NEAREST)

if __name__ == '__main__':

    while True:
        ret, old_frame = cap.read()
        copy_frame = old_frame .copy()
        #Mosaic
        new_frame = mosaic(copy_frame)

        cv2.imshow('OldRawFrame', old_frame)
        cv2.imshow('NewRawFrame', new_frame)
        
        k = cv2.waitKey(1)
        if k == 27:
            break
            
    cap.release()
    cv2.destroyAllWindows()

A little commentary

cap = cv2.VideoCapture(0)

Read video or camera image Enter the video path in () to load the video data

In the case of camera images, 0 is the built-in camera, 1 is the USB camera ...?

ret, old_frame = cap.read()

Load the loaded video frame by frame True / False is entered for ret If it is not read correctly, ret = False and it will be killed.

1 frame image data is input to old_flame It is a video by looping with a while statement

k = cv2.waitKey(1) if k == 27: break

For program termination I usually use cv2.waitKey (0), but For video, use cv2.waitKey (1)

Escape from while only when k == 27 (press Esc) If you put print (k) before the if statement, you can find the button number, so please use any number you like!

Output result

python camera_mosaic.py

When you run the above script, the webcam with the mosaic should start moving.

(For some reason, I couldn't attach the GIF, so please see HUE-chan's still image ...) hue.PNG

There was no delay in the webcam than I expected, so I think I can make various things with this Next time, I plan to create a program that recognizes faces and applies mosaics (˘ω˘)

Recommended Posts

Try processing images and webcams Part 3 ~ Mosaic processing ~
Data analysis planning collection processing and judgment (Part 1)
Data analysis planning collection processing and judgment (Part 2)