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
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
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

Shrink the part you want to mosaic and restore it
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()
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
Command line

Image mosaic
When ratio = 0.1

When ratio = 0.9

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.
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()
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!
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 ...)

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 (˘ω˘)