This article is participating in Python Theme Month. See the link to the event for more details

Is not every time steal the emoticon package, all feel fuzzy feeling, want to find a clear point

To observe the

  1. The blur is just little black dots
  2. Just remove the little black spots and you’ll be clear

Let’s see what it looks like

The original image After repair

Doesn’t it look good

Want to thinking

  1. How do I get rid of the little black dots and get every pixel
  2. Turn the small black dots into white ones

To operate

  1. Look at each pixel value to find the range of small black dots

    • It’s in the 200-230 range

  2. Find the color of your eyes and mouth to prevent your eyes from turning white

    • In about 20-140

  3. We go through each pixel

    • 200-230 color add dozens, whiter, no more than 255
    • 20-140, subtract dozens from the color, make it black, you can’t set zero, it’s too black
  4. Code thinking

    • Read the pictures
    • Traverse the pixels
    • More repair degree calculated, white or black

In the code

Code ability is limited, write not good, interested can study

# !/usr/bin/python3
import threading
import uuid
from tkinter import *
from tkinter import filedialog, messagebox

import cv2
from PIL import ImageTk, Image


class MY_GUI() :

    def __init__(self, init_window_name) :
        self.init_window_name = init_window_name
        self.out_frame = None
        self.in_frame = None

    # Draw window
    def set_init_window(self) :
        self.init_window_name.title("Image manipulation")  # window name
        self.init_window_name.geometry('950x681+10+10')

        self.input_label = Label(self.init_window_name, text="Path:")
        self.input_label.place(x=0, y=0, width=80, height=30)
        self.input_path = Entry(self.init_window_name)
        self.input_path.place(x=80, y=0, width=850, height=30)

        self.init_data_label = Label(self.init_window_name, text="Before repair")
        self.init_data_label.place(x=0, y=60, width=80, height=30)
        self.result_data_label = Label(self.init_window_name, text="After repair")
        self.result_data_label.place(x=550, y=60, width=80, height=30)

        self.in_img_button = Button(self.init_window_name, text="Select picture", bg="lightblue", width=10,
                                    command=self.select_in_frame)
        self.in_img_button.place(x=400, y=100, width=150, height=30)

        self.degree_label = Label(self.init_window_name, text="Degree of repair (1-10)")
        self.degree_label.place(x=400, y=150, width=150, height=30)
        self.degree_input = Spinbox(self.init_window_name, from_=1, to=10)  Call internal method plus () for direct call
        self.degree_input.place(x=400, y=180, width=150, height=30)
        
        self.repair_button = Button(self.init_window_name, text="Repair", bg="lightblue", width=10,
                                    command=self.access_pixels)
        self.repair_button.place(x=400, y=230, width=150, height=30)
        self.d_img_button = Button(self.init_window_name, text="Save", bg="lightblue", width=10,
                                   command=self.d_img)
        self.d_img_button.place(x=400, y=280, width=150, height=30)

    def select_in_frame(self) :
        path = filedialog.askopenfilename()
        if path is None or path == ' ':
            messagebox.showinfo("Tip"."Please select a picture")
            return
        self.input_path.delete(0, END)
        self.input_path.insert(0, path)
        frame = cv2.imread(path)
        self.in_frame = frame

    # here is the code to fix the image
    def access_pixels(self) :
        if self.in_frame is None:
            messagebox.showinfo("Tip"."Please select a picture")
            return
        degreeStr = self.degree_input.get()
        if degreeStr is None or degreeStr == ' ':
            degreeStr = '0'

        degree = int(degreeStr)
        if degree < 1:
            degree = 1
        elif degree > 10:
            degree = 10

        frame = self.in_frame.copy()

        print(frame.shape)  Shape contains three elements: height, width and number of channels in order
        height = frame.shape[0]
        weight = frame.shape[1]
        channels = frame.shape[2]

        showImgHeight = int(height / (weight / 400))
        This is to convert RGB or save it will change color
        b1, g1, r1 = cv2.split(self.in_frame.copy())
        rgb_img1 = cv2.merge([r1, g1, b1])
        im = Image.fromarray(cv2.resize(rgb_img1, (400, showImgHeight)))
        imgtk = ImageTk.PhotoImage(image=im)

        self.before2_img = Label(self.init_window_name, image=imgtk).place(x=0, y=90, width=400,
                                                                           height=showImgHeight)
        print("weight : %s, height : %s, channel : %s" % (weight, height, channels))
        for row in range(height):  # traversal is high
            for col in range(weight):  # traverse wide
                for c in range(channels):  # Easy access
                    pv = frame[row, col, c]
                    # Here is to judge whether it is a small black dot
                    if pv > 23 * (11 - degree):
                        # Here is the calculation to increase the white original color + repair degree *10, prevent too white color is the same
                        if (pv + degree * 10) > 255:
                            frame[row, col, c] = 255
                        else:
                            frame[row, col, c] = (pv + degree * 10)
                    # Here is to judge black, whether it needs to be more black
                    if pv < degree * 15:
                        frame[row, col, c] = 0

        self.out_frame = frame
        b, g, r = cv2.split(self.out_frame.copy())
        rgb_img = cv2.merge([r, g, b])
        im2 = Image.fromarray(cv2.resize(rgb_img, (400, showImgHeight)))
        imgtk2 = ImageTk.PhotoImage(image=im2)
        self.img2 = Label(self.init_window_name, image=imgtk2).place(x=550, y=90, width=400, height=showImgHeight)
        self.img2.place()

    def d_img(self) :
        if self.out_frame is None:
            messagebox.showinfo("Tip"."Please fix the picture first.")
            return
        path = filedialog.askdirectory()
        if path is None or path == ' ':
            messagebox.showinfo("Tip"."Please select an output path")
            return
        savepath = path + "/repair-" + str(uuid.uuid4()) + ".png"
        cv2.imwrite(savepath, self.out_frame)


if __name__ == '__main__':
    init_window = Tk()
    ZMJ_PORTAL = MY_GUI(init_window)
    ZMJ_PORTAL.set_init_window()
    init_window.mainloop()

Copy the code

Code almost, see the effect, there are not understand can comment ask

The effect is ok, not suitable for complex colors of emojis, simple colors are ok