底下是本人常用的功能,重新包裝成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)