前言
物件接到朋友的委託將幾十張截圖的鞋子圖片進行裁剪,再貼上鞋子的款式。想著這不是可以使用指令碼來完成嗎,人工多累呀。
圖片裁剪
使用 Image庫中的crop函式,傳入的引數是一個座標元組,左上角的座標和右下角的座標。(x1,y1,x2,y2),裁剪好之後使用save儲存。
def crop_img(img_path,save_name):
img = Image.open(img_path)
filename = img.filename[:-4]
# 獲取鞋子的位置(根據實際情況調整)
shoes_box = (0, 400, 1080, 1250) # 左上X,左上Y,右下X,右下Y
shoes_img = img.crop(shoes_box)
shoes_img.save(save_name)
print('crop save ok')
return save_name
文字識別
使用pytesseract來實現,使用其中的函式image_to_string()來識別。需要先安裝tesseract。安裝地址https://digi.bib.uni-mannheim.de/tesseract/?C=M;O=D
效果還不錯。
庫安裝
pip install pytesseract
安裝庫,
再安裝tesseract,上面連結地址,然後安裝好後將軟體的安裝地址加入環境變數。
使用tesseract --version可以檢測安裝是否成功。
如果不配置環境變數就不會使用預設路徑來執行tesseract。
中文識別
使用官方預設不支援識別中文,需要下載中文包。地址https://github.com/tesseract-ocr/tessdata/tree/main 中的chi_sim.traineddata。為中文簡體包。下載下來之後放入tesseract的tessdata目錄下。
就可以使用pytesseract.image_to_string(img,lang='chi_sim')
來識別中文了。
def ocr_text(img_path):
img = Image.open(img_path).convert('L') #L表示以灰度模式開啟,可提高檢測效果
text = pytesseract.image_to_string(img,lang='chi_sim1')
part = r'鞋.*款'
match_ = re.search(part, text).group()[1::].replace(' ', '')
# print(text)
return match_
文字新增
def cv2_img_add_text_with_bg(img_path,
result_img_path,
text: str,
left: int,
top: int,
textColor=(255, 0, 0),
textSize=20,
bgColor=(0, 0, 0), # 新增:文字背景顏色,預設為黑色
bgPadding=(5, 5), # 新增:文字背景邊緣 padding,預設各方向5畫素
filepath="D:\\app\\ocr\\tessdata\\simsun.ttc",
):
"""
在圖片上寫中文文字,並帶有指定顏色的背景
"""
img = cv2.imread(img_path)
if isinstance(img, np.ndarray): # 確保是OpenCV影像格式
img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
else:
raise TypeError("img must be a numpy ndarray")
draw = ImageDraw.Draw(img_pil)
fontStyle = ImageFont.truetype(filepath, textSize, encoding="utf-8")
# 計算文字框的尺寸以確定背景矩形的大小
# 使用getbbox()方法間接獲取文字尺寸,注意getbbox返回的是一個包含左上角和右下角座標的元組
text_bbox = draw.textbbox((0, 0), text, font=fontStyle)
textWidth = text_bbox[2] - text_bbox[0]
textHeight = text_bbox[3] - text_bbox[1]
# 繪製背景矩形
bgLeft = left - bgPadding[0]
bgTop = top - bgPadding[1]
draw.rectangle([(bgLeft, bgTop), (bgLeft + textWidth, bgTop + textHeight)], fill=bgColor)
# 繪製文字
draw.text((left, top), text, textColor, font=fontStyle)
# 轉換回OpenCV格式並返回
img_text = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
cv2.imwrite(result_img_path,img_text)
print('put ok')
中文字型下載http://xiazaiziti.com/category/zhongwenziti
例項程式碼和效果
import pytesseract
import re
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import cv2
import os
# 讀取圖片
num = 1
def crop_img(img_path,save_name):
img = Image.open(img_path)
filename = img.filename[:-4]
# 獲取鞋子的位置(根據實際情況調整)
shoes_box = (0, 400, 1080, 1250) # 左上X,左上Y,右下X,右下Y
shoes_img = img.crop(shoes_box)
shoes_img.save(save_name)
print('crop save ok')
return save_name
img_path = "D:\\Desktop\\1.jpg"
img_crop_path = "D:\\Desktop\\1_crop.jpg"
# crop_img(img_path)
def ocr_text(img_path):
img = Image.open(img_path).convert('L') #L表示灰度模式,可提高檢測效果
text = pytesseract.image_to_string(img,lang='chi_sim1')
part = r'鞋.*款'
match_ = re.search(part, text).group()[1::].replace(' ', '')
# print(text)
return match_
def cv2_img_add_text_with_bg(img_path,
result_img_path,
text: str,
left: int,
top: int,
textColor=(255, 0, 0),
textSize=20,
bgColor=(0, 0, 0), # 新增:文字背景顏色,預設為黑色
bgPadding=(5, 5), # 新增:文字背景邊緣 padding,預設各方向5畫素
filepath="D:\\app\\ocr\\tessdata\\simsun.ttc",
):
"""
在圖片上寫中文文字,並帶有指定顏色的背景
"""
img = cv2.imread(img_path)
if isinstance(img, np.ndarray): # 確保是OpenCV影像格式
img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
else:
raise TypeError("img must be a numpy ndarray")
draw = ImageDraw.Draw(img_pil)
fontStyle = ImageFont.truetype(filepath, textSize, encoding="utf-8")
# 計算文字框的尺寸以確定背景矩形的大小
# 使用getbbox()方法間接獲取文字尺寸,注意getbbox返回的是一個包含左上角和右下角座標的元組
text_bbox = draw.textbbox((0, 0), text, font=fontStyle)
textWidth = text_bbox[2] - text_bbox[0]
textHeight = text_bbox[3] - text_bbox[1]
# 繪製背景矩形
bgLeft = left - bgPadding[0]
bgTop = top - bgPadding[1]
draw.rectangle([(bgLeft, bgTop), (bgLeft + textWidth, bgTop + textHeight)], fill=bgColor)
# 繪製文字
draw.text((left, top), text, textColor, font=fontStyle)
# 轉換回OpenCV格式並返回
img_text = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
cv2.imwrite(result_img_path,img_text)
print('put ok')
def get_file_names(directory):
"""
返回指定目錄下所有檔案的名稱列表(不包括子目錄中的檔案)。
:param directory: 要讀取的目錄路徑
:return: 檔名列表
"""
# 確保給定的路徑是絕對路徑,以避免相對路徑可能引起的錯誤
abs_directory = os.path.abspath(directory)
# 使用listdir()獲取目錄中的所有條目
entries = os.listdir(abs_directory)
# 過濾出檔案(而非子目錄)
file_names = [entry for entry in entries if os.path.isfile(os.path.join(abs_directory, entry))]
return file_names
if __name__ == "__main__":
num =1
save_directory = 'D:\\Desktop\\save\\crop\\'
file_ = 'D:\\app\\QQ\\Filerev\\'
filelist = get_file_names(file_)
for file in filelist:
file_path = file_ +file
text = ocr_text(file_path)
print(text)
cro_save_file_name = save_directory + file
crop_img(file_path,cro_save_file_name)
result_img = 'D:\\Desktop\\save\\result\\'+file
cv2_img_add_text_with_bg(cro_save_file_name, result_img,text, 800, 750, textColor=(255, 255, 255), textSize=70)
將下面這張圖片
轉成: