底下是本人常用的功能,重新包裝成SDK,主程式只需 import 即可使用。
from MahalSdk.cv import cv
img=cv.read('tiger.jpg')
img=cv.resize(img, width=800)
img=cv.shift(img, 100, 50)
cv.show(img)
plt.show()
SDK
請將底下的 SDK 置於專案下的 MahalSdk 目錄之下,檔名為 cv.py。
"""
Ver 1.0.0
initial : 2024-11-08
pip install opencv-python matplotlib
"""
import platform
import cv2
import numpy as np
from PIL import Image, ImageFont, ImageDraw
import pylab as plt
from PySide6.QtGui import QImage, QPixmap
class cv():
Vertical = 0
Horizontal = 1
Both = -1
#讀檔
@staticmethod
def read(file):
# return cv2.imdecode(
# np.fromfile(file, dtype=np.uint8),
# cv2.IMREAD_COLOR
# )
return np.array(Image.open(file))[:,:,::-1].copy()
#縮圖
@staticmethod
def resize(img, width=800):
# if height is None:
# h, w, _ = img.shape
# rate=width/w
# height=int(h*rate)
# img=cv2.resize(
# img.copy(),
# (width, height),
# interpolation=cv2.INTER_LINEAR
# )
# return img
pil=Image.fromarray(img)
#pil.thumbnail((width, height))
pil.thumbnail((width, 100000))
return np.array(pil)
# 存檔
@staticmethod
def write(img, file):
# cv2.imwrite(file,img,[cv2.IMWRITE_JPEG_QUALITY,90])
# cv2.imencode('.jpg',img)[1].tofile(file)
Image.fromarray(img[:,:,::-1].copy()).save(file)
#裁切
@staticmethod
def crop(img, p1, p2):
return img[p1[1]:p2[1], p1[0]:p2[0]]
#平移
@staticmethod
def shift(img, x, y):
h, w, _ = img.shape
m=np.float32([
[1,0,x],
[0,1,y]
])
return cv2.warpAffine(img, m, (w, h))
#旋轉
@staticmethod
def rotate(img, angle=0, center=None, scale=1):
h, w, _ = img.shape
if center is None:
x=(w-1)/2
y=(h-1)/2
else:
x=center[0]
y=center[1]
m=cv2.getRotationMatrix2D((x, y), angle, scale)
return cv2.warpAffine(img, m, (w, h))
#鏡射
@staticmethod
def flip(img, direction=Horizontal):
return cv2.flip(img, direction)
#透視圖
@staticmethod
def perspective(img, ps1, ps2, width, height):
h, w, _ = img.shape
m = cv2.getPerspectiveTransform(ps1, ps2)
return cv2.warpPerspective(img, m, (width, height))
#空白圖片
@staticmethod
def blank(width=100, height=100, color=(255,255,255)):
img=np.zeros([height, width, 3], dtype=np.uint8)
img[:,:]=color
return img
#畫線
@staticmethod
def line(img, p1, p2, color=(0,0,0), width=1):
cv2.line(img, p1, p2, color, width)
return img
#矩型
@staticmethod
def rectangle(img, p1, p2, color=(0,0,0), width=1):
cv2.rectangle(
img,
p1, p2,
color,
width,
cv2.LINE_AA
)
return img
#正圓型
@staticmethod
def circle(img, center=None, radius=10, color=(0,0,0), width=1):
if center is None:
h, w, _= img.shape
center=(int((w-1)/2), int((h-1)/2))
cv2.circle(img, center, radius, color, width)
return img
#寫入文字
@staticmethod
def text(img, text, xy=(0,0), color=(0,0,0), size=12):
pil = Image.fromarray(img)
s=platform.system()
if s == "Linux":
font = (
ImageFont.truetype(
'/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc', size)
)
elif s=="Darwin":
font = ImageFont.truetype('....', size)
else:
font = ImageFont.truetype('simsun.ttc', size)
ImageDraw.Draw(pil).text(xy, text, font=font, fill=color)
return np.asarray(pil)
#透明矩型
@staticmethod
def alphaRect(img, text, xy=(0,0), bgcolor=(0,0,0,50), fontcolor=(255,255,255), size=12):
pil = Image.fromarray(img)
s=platform.system()
if s == "Linux":
font = (
ImageFont.truetype(
'/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc', size)
)
elif s=="Darwin":
font = ImageFont.truetype('....', size)
else:
font = ImageFont.truetype('simsun.ttc', size)
draw=ImageDraw.Draw(pil, 'RGBA')
x1, y1, x2, y2=draw.textbbox(xy, text=text, font=font)
x2+=4
y2+=4
draw.rectangle((x1, y1, x2, y2), fill=bgcolor )
draw.text((x1+2, y1+2), text, font=font, fill=fontcolor)
return np.asarray(pil)
#畫橢圓
@staticmethod
def ellipse(img, center, axes, angle=0, startAngle=0, endAngle=360, color=(0,0,0), width=-1):
cv2.ellipse(img, center, axes , angle, startAngle, endAngle, color, width, cv2.LINE_AA)
return img
#多邊型
@staticmethod
def polylines(img, pts, color=(0,0,0), isClosed=True, width=1):
cv2.polylines(img, pts=[pts], isClosed=isClosed, color=color, thickness=width)
return img
#blur
@staticmethod
def blur(img, w=1, h=1):
return cv2.blur(img, (w, h))
#sharp
@staticmethod
def sharp(img, kernel=np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)):
return cv2.filter2D(img, -1, kernel=kernel)
@staticmethod
def canny(img, h1, h2):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
return cv2.Canny(blurred, h1, h2)
@staticmethod
def erode(img, kernel=None, iterations=1):
if kernel is None:
kernel=np.ones((3,3), np.uint8)
return cv2.erode(img, kernel=kernel, iterations=iterations)
@staticmethod
def dilate(img, kernel=None, iterations=1):
if kernel is None:
kernel=np.ones((3,3), np.uint8)
return cv2.dilate(img, kernel=kernel, iterations=iterations)
#cv2 to QImage
@staticmethod
def cv2qimage(img):
#img = img[..., ::-1].copy()
h, w, _=img.shape
img = QImage(img[:,:,::-1].copy(), w, h, w * 3, QImage.Format_RGB888)
return img
# cv2 to QPixmap
@staticmethod
def cv2pixmap(img):
#img = img[..., ::-1].copy()# QImage只能使用深度複製
h, w, _=img.shape
img = QImage(img[:,:,::-1].copy(), w, h, w * 3, QImage.Format_RGB888)
pix = QPixmap(img)
return pix
@staticmethod
def imshow(img, row=1, col=1, area=1, axis="off"):
ax=plt.subplot(row, col, area)
ax.imshow(img[:,:,::-1])
ax.axis(axis)
