Paint-Brush đơn giản trong opencv

Trong bài viết lần này mình sẽ giới thiệu đến các bạn cách xây dựng một ứng dụng paint đơn giản bằng opencv Bài viết này mình sẽ sử dụng opencv để vẽ các hình khác nhau. Mình sừ dụng các hàm hàm draw cơ bản của opencv như: cv2.line (), cv2.circle (), cv2.rectangle (), cv2.ellipse (), cv2.putText () vv Trước tiên, các hàm kể trên thường sử dụng các đối số sau:

  • img: Hình ảnh bạn muốn vẽ vào color: Màu sắc của hình bạn định vẽ. Với BGR, ta sẽ truyền vào một bộ 3 giá trụ, ví dụ: (255,0,0) cho màu xanh lam. Đối với màu xám, chỉ cần truyền giá trị vô hướng. thickness: Độ dày của đường kẻ hoặc đường tròn. Nếu - 1 được truyền cho các hình khép kín ví dụ như hình tròn, hình sẽ được điền đầy cae viền và bên trong. độ dày mặc định là 1 lineType: Loại line, có thể chọn 8-connected, anti-aliased line, vv. mặc định là 8-connected. Nếu bạn truyền vào cv2.LINE_AA ta sẽ có một đường cong mịn (không có răng cưa).

Vẽ đường thẳng

Để vẽ một đường thẳng, bạn cần phải biết tọa độ điểm bắt đầu và kết thúc của đường kẻ. Ví dụ dưới đây sẽ tạo ra một hình ảnh màu đen và vẽ một đường màu đỏ trên nó từ góc trên bên trái sang góc dưới bên phải.

import numpy as np
import cv2

# Create a black image
img = np.zeros((512,512,3), np.uint8)

# Draw a diagonal blue line with thickness of 5 px
cv2.line(img,(0,0),(511,511),(255,0,0),5)

Vẽ hình chữ nhật

Để vẽ hình chữ nhật, bạn cần biế góc trên cùng bên trái và góc dưới cùng bên phải của hình chữ nhật. Lần này chúng ta sẽ vẽ một hình chữ nhật màu xanh lá cây ở góc trên bên phải của hình ảnh.

cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)

Vẽ hình tròn

Để vẽ một vòng tròn, bạn cần có tọa độ tâm và bán kính. Chúng ta sẽ vẽ một vòng tròn bên trong hình chữ nhật được vẽ ở trên.

cv2.circle (img, (447,63), 63, (0,0,255), -1)

Vẽ hình ellip

Để vẽ ellip, chúng ta cần phải truyền vào một số đối số. Một đối số đầu tiên là tọa độ vị trí tâm (x, y). Đối số tiếp theo là độ dài trục (chiều dài trục chính, độ dài trục nhỏ). góc quay của hình elip theo chiều ngược chiều kim đồng hồ. startAngle và endAngle biểu thị bắt đầu và kết thúc của hồ quang hình elip được đo theo chiều kim đồng hồ từ trục chính. nghĩa là cho các giá trị 0 và 360 cho phép hình elip đầy đủ. Dưới đây ví dụ vẽ một ellipse nửa ở trung tâm của hình ảnh.

cv2.ellipse (img, (256,256), (100,50), 0,0,180,255, -1)

Vẽ đa giác

Để vẽ đa giác, đầu tiên bạn cần tọa độ của các đỉnh. Cho những điểm nàyvào một mảng của có dạng ROWSx1x2 trong đó ROWS là số đỉnh và phải là kiểu int32. Sau đây chúng ta sẽ vẽ một đa giác nhỏ với bốn đỉnh màu xanh.

pts = np.array([[150,50],[20,30],[400,200],[300,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv2.polylines (img, [pts], True, (0,255,255))

Chèn text vào hình ảnh

Để đưa văn bản vào hình ảnh, bạn cần truyền vào những tham số sau:

  • Dữ liệu văn bản mà bạn muốn viết
  • Vị trí tọa độ nơi bạn muốn đặt (góc dưới cùng bên trái nơi dữ liệu bắt đầu).
  • Kiểu chữ
  • Quy mô Phông (xác định kích thước của phông chữ)
  • một số đối số khác như như màu sắc, độ dày, lineType, vv Dưới đây mà một ví dụ chèn chữ màu trắng lên ảnh
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'Yang Long',(10,500), font, 2,(255,255,255),2,cv2.LINE_AA)

Demo

  1. Tạo ứng dụng đơn giản để vẽ một hình tròn trên một hình ảnh bất cứ nơi nào chúng ta nhấp đúp vào

Đầu tiên chúng ta tạo một hàm mouse callback được thực hiện khi một mouse event diễn ra. Sự kiện mouse event có thể liên quan đến chuột như nút trái, nút bên trái, nút bên trái nhấp đúp chuột ... Nó cho chúng ta tọa độ (x, y) cho mỗi mouse event. Với sự kiện và địa điểm này, chúng ta có thể làm bất cứ điều gì chúng tôi muốn. Để liệt kê tất cả các sự kiện có sẵn, hãy chạy đoạn sau:

>>> import cv2
>>> events = [i for i in dir(cv2) if 'EVENT' in i]
>>> print events

Tạo hàm mouse callback có một format giống nhau ở mọi nơi.

import cv2
import numpy as np

# mouse callback function
def draw_circle(event,x,y,flags,param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img,(x,y),100,(255,0,0),-1)

# Create a black image, a window and bind the function to window
img = np.zeros((512,512,3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

while(1):
    cv2.imshow('image',img)
    if cv2.waitKey(20) & 0xFF == 27:
        break
cv2.destroyAllWindows()

2. Vẽ hình tròn hoặc hình chữ nhật Bây giờ chúng ta sẽ vẽ hình chữ nhật hoặc hình tròn (tùy thuộc vào chế độ chúng ta chọn) bằng cách kéo chuột giống như trong Paint. Vì vậy hàm mouse callback của chúng ta có hai phần, một để vẽ hình chữ nhật và một để vẽ các hình vẽ khác.

import cv2
import numpy as np

drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix,iy = -1,-1

# mouse callback function
def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy = x,y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                cv2.circle(img,(x,y),5,(0,0,255),-1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
        else:
            cv2.circle(img,(x,y),5,(0,0,255),-1)

img = np.zeros((512,512,3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

while(1):
    cv2.imshow('image',img)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break

cv2.destroyAllWindows()