一、期末大作业
1、游戏🎮《别再踩白块了》辅助器项目
![](https://img.haomeiwen.com/i21107801/29feac1a06fb5046.png)
import cv2
import numpy as np
from matplotlib import pyplot as plt
from win32api import GetSystemMetrics
from win32con import SRCCOPY,SM_CXSCREEN,SM_CYSCREEN
from win32gui import FindWindow, GetWindowDC, DeleteObject, ReleaseDC,GetDesktopWindow
from win32ui import CreateDCFromHandle, CreateBitmap
import time
import pyautogui
import sys
import threading
# 左上和右上坐标
class GameStart():
# 点击屏幕并且获取坐标
def __init__(self):
self.first_pointX=0
self.first_pointY=0
self.second_pointX=0
self.second_pointY=0
self.clock_number=0
self.center_post_list=[]
def on_EVENT_LBUTTONDOWN(self,event, x, y, flags, param):
if (self.clock_number > 1):
cv2.destroyWindow('image')
# 左键按下
if event == cv2.EVENT_LBUTTONDOWN:
# 输出坐标信息
xy = "%d,%d" % (x, y)
print(xy)
if(self.clock_number==0):
self.first_pointX=x
self.first_pointY=y
elif(self.clock_number==1):
self.second_pointX = x
self.second_pointY = y
self.clock_number+=1
def windowshots(self,x1, y1, x2, y2):
w, h = x2 - x1, y2 - y1
hdesktop = GetDesktopWindow()
wDC = GetWindowDC(hdesktop)
dcObj = CreateDCFromHandle(wDC)
cDC = dcObj.CreateCompatibleDC()
dataBitMap = CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, w, h)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0, 0), (w, h), dcObj, (x1, y1), SRCCOPY)
signedIntsArray = dataBitMap.GetBitmapBits(True)
DeleteObject(dataBitMap.GetHandle())
cDC.DeleteDC()
dcObj.DeleteDC()
ReleaseDC(hdesktop, wDC)
screen = np.frombuffer(signedIntsArray, dtype='uint8')
screen.shape = (h, w, 4)
screen = cv2.cvtColor(screen, cv2.COLOR_BGRA2BGR)
return screen
def press(self,key):
print(key.char)
def plt_show0(self,img):
b, g, r = cv2.split(img)
img = cv2.merge([r, g, b])
plt.imshow(img)
plt.show()
def plt_show(self,img):
plt.imshow(img, cmap="gray")
plt.show()
def get_pos(self,contours):
pos_list = []
for contour in contours:
rect = cv2.boundingRect(contour)
x, y, weight, height = rect
pos_list.append([x, y + height])
return pos_list
def speed_pos(self,contours, Min_Area=6500):
chunk_contours = []
for item in contours:
if cv2.contourArea(item) > Min_Area:
# 用最小巨型进行包裹
rect = cv2.boundingRect(item)
x, y, weight, height = rect
if (height > 120):
for next_y in range(int(height / 120) + 1):
next_y += 1
chunk_contours.append([x + weight / 8, y + 120 * next_y])
else:
chunk_contours.append([x + weight / 8, y + height])
return chunk_contours
def start(self):
max_win_width=GetSystemMetrics(SM_CXSCREEN)
max_win_height=GetSystemMetrics(SM_CYSCREEN)
img=self.windowshots(0,0,max_win_width,max_win_height)
cv2.namedWindow("image",cv2.WINDOW_KEEPRATIO)
cv2.setMouseCallback("image", self.on_EVENT_LBUTTONDOWN)
cv2.imshow("image",img)
cv2.waitKey(0)
time.sleep(0.5)
while(1):
img = self.windowshots(self.first_pointX,self.first_pointY,self.second_pointX,self.second_pointY)
img=np.asarray(img)
cv2.imwrite("image.png", img)
img_gray=img.copy()
img_gray=cv2.cvtColor(img_gray,cv2.COLOR_BGR2GRAY)
ret,img_threshold=cv2.threshold(img_gray,60,255,cv2.THRESH_BINARY_INV)
kernelY=cv2.getStructuringElement(cv2.MORPH_RECT,(5,7))
image = cv2.morphologyEx(img_threshold, cv2.MORPH_CLOSE, kernelY, iterations=1)
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
image = cv2.erode(image, kernelX)
contours,hierarchy=cv2.findContours(image,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
self.center_post_list=self.speed_pos(contours)
self.center_post_list=sorted(self.center_post_list, key=lambda tup: tup[1],reverse=True)
if (len(self.center_post_list)==0):
break
def work(self):
while (1):
for pos in self.center_post_list:
print(self.center_post_list)
pyautogui.moveTo(int(pos[0] + self.first_pointX), int(pos[1] +self.first_pointY), duration=0)
pyautogui.click()
break
if __name__ == '__main__':
Start=GameStart()
t1 = threading.Thread(target=Start.start)
t2 = threading.Thread(target=Start.work)
t1.start()
t2.start()
2、发票和收据🧾文本 OCR 识别项目
![](https://img.haomeiwen.com/i21107801/7f0a9962c4b0aeee.png)
import cv2
import numpy as np
import pytesseract
import os
# C:\Program Files\Tesseract-OCR
per = 25
pixelThreshold=500
roi = [[(98, 984), (680, 1074), 'text', 'Name'],
[(740, 980), (1320, 1078), 'text', 'Phone'],
[(98, 1154), (150, 1200), 'box', 'Sign'],
[(738, 1152), (790, 1200), 'box', 'Allergic'],
[(100, 1418), (686, 1518), 'text', 'Email'],
[(740, 1416), (1318, 1512), 'text', 'ID'],
[(110, 1598), (676, 1680), 'text', 'City'],
[(748, 1592), (1328, 1686), 'text', 'Country']]
pytesseract.pytesseract.tesseract_cmd = 'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'
imgQ = cv2.imread('Query.png')
h,w,c = imgQ.shape
#imgQ = cv2.resize(imgQ,(w//3,h//3))
orb = cv2.ORB_create(1000)
kp1, des1 = orb.detectAndCompute(imgQ,None)
#impKp1 = cv2.drawKeypoints(imgQ,kp1,None)
path = 'UserForms'
myPicList = os.listdir(path)
print(myPicList)
for j,y in enumerate(myPicList):
img = cv2.imread(path + "/" + y)
img = cv2.resize(img, None, fx=0.4, fy=0.4) # 这里调整图片大小
#img = cv2.resize(img, (w // 3, h // 3))
# cv2.imshow(y, img)
kp2, des2 = orb.detectAndCompute(img,None)
bf = cv2.BFMatcher(cv2.NORM_HAMMING)
matches = bf.match(des2,des1)
# matches.sort(key= lambda x: x.distance)
matches = sorted(matches, key=lambda x: x.distance)
good = matches[:int(len(matches)*(per/100))]
imgMatch = cv2.drawMatches(img,kp2,imgQ,kp1,good[:100],None,flags=2)
# cv2.imshow(y, imgMatch)
srcPoints = np.float32([kp2[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dstPoints = np.float32([kp1[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
M, _ = cv2.findHomography(srcPoints,dstPoints,cv2.RANSAC,5.0)
imgScan = cv2.warpPerspective(img,M,(w,h))
#cv2.imshow(y, imgScan)
imgShow = imgScan.copy()
imgMask = np.zeros_like(imgShow)
myData = []
print(f'################## Extracting Data from Form {j} ##################')
for x,r in enumerate(roi):
cv2.rectangle(imgMask, (r[0][0],r[0][1]),(r[1][0],r[1][1]),(0,255,0),cv2.FILLED)
imgShow = cv2.addWeighted(imgShow,0.99,imgMask,0.1,0)
imgCrop = imgScan[r[0][1]:r[1][1], r[0][0]:r[1][0]]
# cv2.imshow(str(x), imgCrop)
if r[2] == 'text':
print('{} :{}'.format(r[3],pytesseract.image_to_string(imgCrop)))
myData.append(pytesseract.image_to_string(imgCrop))
if r[2] =='box':
imgGray = cv2.cvtColor(imgCrop,cv2.COLOR_BGR2GRAY)
imgThresh = cv2.threshold(imgGray,170,255, cv2.THRESH_BINARY_INV)[1]
totalPixels = cv2.countNonZero(imgThresh)
if totalPixels>pixelThreshold: totalPixels =1;
else: totalPixels=0
print(f'{r[3]} :{totalPixels}')
myData.append(totalPixels)
cv2.putText(imgShow,str(myData[x]),(r[0][0],r[0][1]),
cv2.FONT_HERSHEY_PLAIN,2.5,(0,0,255),4)
with open('DataOutput.csv','a+') as f:
for data in myData:
f.write((str(data)+','))
f.write('\n')
#imgShow = cv2.resize(imgShow, (w // 3, h // 3))
print(myData)
# cv2.imshow(y+"2", imgShow)
cv2.imshow(y + "2", cv2.resize(imgShow, None, fx=0.4, fy=0.4))
cv2.imwrite(y,imgShow)
# cv2.imshow("KeyPointsQuery",impKp1)
# cv2.imshow("Output",imgQ)
# cv2.waitKey(0)
######### Region Selector ###############################
"""
This script allows to collect raw points from an image.
The inputs are two mouse clicks one in the x,y position and
the second in w,h of a rectangle.
Once a rectangle is selected the user is asked to enter the type
and the Name:
Type can be 'Text' or 'CheckBox'
Name can be anything
"""
import cv2
import random
path = 'Query.png'
scale = 0.5
circles = []
counter = 0
counter2 = 0
point1=[]
point2=[]
myPoints = []
myColor=[]
def mousePoints(event,x,y,flags,params):
global counter,point1,point2,counter2,circles,myColor
if event == cv2.EVENT_LBUTTONDOWN:
if counter==0:
point1=int(x//scale),int(y//scale);
counter +=1
myColor = (random.randint(0,2)*200,random.randint(0,2)*200,random.randint(0,2)*200 )
elif counter ==1:
point2=int(x//scale),int(y//scale)
type = input('Enter Type')
name = input ('Enter Name ')
myPoints.append([point1,point2,type,name])
counter=0
circles.append([x,y,myColor])
counter2 += 1
img = cv2.imread(path)
img = cv2.resize(img, (0, 0), None, scale, scale)
while True:
# To Display points
for x,y,color in circles:
cv2.circle(img,(x,y),3,color,cv2.FILLED)
cv2.imshow("Original Image ", img)
cv2.setMouseCallback("Original Image ", mousePoints)
if cv2.waitKey(1) & 0xFF == ord('s'):
print(myPoints)
break
3、基于 CVzone 的停车位🚗检测项目
![](https://img.haomeiwen.com/i21107801/81539502a8454709.png)
import cv2 # 导入OpenCV库
import pickle # 导入pickle模块
import cvzone # 导入cvzone库
import numpy as np # 导入NumPy库
import ctypes # 导入ctypes模块
# 视频源
cap = cv2.VideoCapture('carPark.mp4')
with open('CarParkPos', 'rb') as f:
posList = pickle.load(f) # 从文件中加载位置列表
width, height = 107, 48 # 定义车位区域的宽度和高度
# 获取屏幕分辨率
user32 = ctypes.windll.user32
screen_width, screen_height = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
def checkParkingSpace(imgPro):
spaceCounter = 0 # 计数空闲车位数
for pos in posList: # 遍历每个车位的位置
x, y = pos
imgCrop = imgPro[y:y + height, x:x + width] # 裁剪车位区域
count = cv2.countNonZero(imgCrop) # 计算车位区域非零像素数
if count < 900: # 如果非零像素数小于阈值
color = (0, 255, 0) # 绿色
thickness = 5
spaceCounter += 1
else:
color = (0, 0, 255) # 红色
thickness = 2
cv2.rectangle(img, pos, (pos[0] + width, pos[1] + height), color, thickness) # 绘制车位区域矩形框
cvzone.putTextRect(img, str(count), (x, y + height - 3), scale=1,
thickness=2, offset=0, colorR=color) # 在车位区域绘制非零像素数
cvzone.putTextRect(img, f'Free: {spaceCounter}/{len(posList)}', (100, 50), scale=3,
thickness=5, offset=20, colorR=(0,200,0)) # 显示空闲车位数
play_once = True
while True:
if play_once:
if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
play_once = False
cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
else:
break
success, img = cap.read() # 读取视频帧
if not success:
break
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 将帧转换为灰度图像
imgBlur = cv2.GaussianBlur(imgGray, (3, 3), 1) # 对图像进行高斯模糊处理
imgThreshold = cv2.adaptiveThreshold(imgBlur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 25, 16) # 自适应阈值处理
imgMedian = cv2.medianBlur(imgThreshold, 5) # 中值模糊处理
kernel = np.ones((3, 3), np.uint8)
imgDilate = cv2.dilate(imgMedian, kernel, iterations=1) # 膨胀处理
checkParkingSpace(imgDilate) # 检查车位状态
cv2.namedWindow("Image", cv2.WND_PROP_FULLSCREEN) # 创建全屏窗口
cv2.setWindowProperty("Image", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) # 设置窗口为全屏
cv2.imshow("Image", img) # 显示图像
if cv2.waitKey(10) & 0xFF == ord('q'): # 检测按键
break
cv2.destroyAllWindows() # 关闭所有窗口
cap.release() # 释放视频捕获对象
-
总的来说,感觉学到了很多。门槛低,0基础也能入手
-
里面还有很多有趣的项目我都没空做,大家有兴趣的话拿去复现叭!
参考博主链接:https://space.bilibili.com/46880349?spm_id_from=333.788.0.0
二、课后作业
第1周
from skimage import io,color
from matplotlib import pyplot as plt
import numpy as np
image = io.imread('../image/rock.jpg')
r = image[:,:,0]
g = image[:,:,1]
b = image[:,:,2]
b_template = np.zeros(image.shape, dtype = 'uint8')
for i in range(b.shape[0]):
for j in range(b.shape[1]):
if b[i, j] <= 100:
b_template[i, j] = 1
image2 = image * b_template
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(221),plt.axis('off')
plt.imshow(image),plt.title('原始RGB图像')
plt.subplot(222),plt.axis('off')
plt.imshow(b, cmap='gray'),plt.title('B分量')
plt.subplot(223),plt.axis('off')
plt.imshow(color.rgb2gray(b_template), cmap='gray')
plt.title('蓝色通道模板')
plt.subplot(224),plt.axis('off')
plt.imshow(image2),plt.title('分割后的RGB图像')
plt.show()
![](https://img.haomeiwen.com/i21107801/c677eba7acd2ec41.png)
第2周
from scipy import ndimage
from skimage import io, color
from matplotlib import pyplot as plt
noise_img = io.imread('../image/girl.png')
max_img = ndimage.maximum_filter(noise_img, size=(3, 3))
min_img = ndimage.minimum_filter(noise_img, size=(3, 3))
mean_img = ndimage.uniform_filter(noise_img, size=(3, 3))
gause_img = ndimage.gaussian_filter(noise_img, 3)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(231), plt.axis('off')
plt.imshow(noise_img, cmap='gray'), plt.title('加噪图像')
plt.subplot(232), plt.axis('off')
plt.imshow(max_img, cmap='gray'), plt.title('最大滤波')
plt.subplot(233), plt.axis('off')
plt.imshow(min_img, cmap='gray'), plt.title('最小滤波')
plt.subplot(234), plt.axis('off')
plt.imshow(mean_img, cmap='gray'), plt.title('均值滤波')
plt.subplot(235), plt.axis('off')
plt.imshow(gause_img, cmap='gray'), plt.title('高斯滤波')
plt.show()
![](https://img.haomeiwen.com/i21107801/ad94786f2f8ab7db.png)
第3周
from skimage import filters, io
from matplotlib import pyplot as plt
from scipy import ndimage
noise_img = io.imread('../image/cat.png')
img_median = ndimage.median_filter(noise_img, size = 3)
img_laplace = filters.laplace(img_median, ksize = 3, mask = None)
plt.rcParams['font.sans-serif'] = ['SimHei']
c = [noise_img, img_median, img_laplace]
s = ['原图像', '中值滤波', 'laplace图像']
for r in range(3):
plt.subplot(2, 2, r + 1),plt.axis('off')
plt.imshow(c[r], cmap = 'gray'),plt.title(s[r])
plt.show()
![](https://img.haomeiwen.com/i21107801/08431b76e2617b7d.png)
第4周
import matplotlib.pyplot as plt
from skimage import data
PATCH_SIZE=20
# 载入相机图像
image = data.camera()
# 选择图像中的天空区域块
sky_location =(54, 48)
sky_patch= image[sky_location[0]: sky_location[0] + PATCH_SIZE,
sky_location[1]:sky_location[1]+ PATCH_SIZE]
(y, x)= sky_location
plt.subplot(121)
plt.imshow(image, cmap='gray')
plt.plot(x, y, 'bs')
plt.subplot(122)
plt.imshow(sky_patch, cmap='gray', interpolation='nearest',vmin=0,vmax=255)
plt.show()
![](https://img.haomeiwen.com/i21107801/1b8cdcd872ac4c1f.png)
第5周
# 测试局部二值模式(LBP) 方法对同一图像不同亮度的鲁棒性:
# 1.对于同一幅图像,生成另外3幅不同亮度的國像(共4幅图像)
# 2.获得4幅图像的LBP图像,及其IBP直方图
# 3.计算另外3幅图像的LBP直方图与原图像LBP直方图的误差值(MSE)
from skimage import io, color, exposure, feature
import numpy as np
import matplotlib.pyplot as plt
image = io.imread('../image/face.jpg')
# 调整图像的 gamma 值
image_1 = exposure.adjust_gamma(image, 0.5)
image_2 = exposure.adjust_gamma(image, 2)
image_3 = exposure.adjust_gamma(image, 3)
# 将图像转换为灰度图
img = color.rgb2gray(image)
img1 = color.rgb2gray(image_1)
img2 = color.rgb2gray(image_2)
img3 = color.rgb2gray(image_3)
# 计算局部二值模式(Local Binary Pattern,LBP)特征
texture = feature.local_binary_pattern(img, 8, 1.0, method='default')
textureHist, bins = exposure.cumulative_distribution(texture)
textureHist = textureHist / textureHist.max()
texture1 = feature.local_binary_pattern(img1, 8, 1.0, method='default')
textureHist1, bins = exposure.cumulative_distribution(texture1)
textureHist1 = textureHist1 / textureHist1.max()
texture2 = feature.local_binary_pattern(img2, 8, 1.0, method='default')
textureHist2, bins = exposure.cumulative_distribution(texture2)
textureHist2 = textureHist2 / textureHist2.max()
texture3 = feature.local_binary_pattern(img3, 8, 1.0, method='default')
textureHist3, bins = exposure.cumulative_distribution(texture3)
textureHist3 = textureHist3 / textureHist3.max()
# 打印不同 gamma 值下 LBP 直方图之间的误差
print("LBP直方图误差1:", np.sum((textureHist - textureHist1) ** 2) / len(textureHist))
print("LBP直方图误差2:", np.sum((textureHist - textureHist2) ** 2) / len(textureHist))
print("LBP直方图误差3:", np.sum((textureHist - textureHist3) ** 2) / len(textureHist))
# 绘制图像和直方图
plt.subplot(3, 4, 1), plt.imshow(image), plt.axis('off')
plt.subplot(3, 4, 2), plt.imshow(image_1), plt.axis('off')
plt.subplot(3, 4, 3), plt.imshow(image_2), plt.axis('off')
plt.subplot(3, 4, 4), plt.imshow(image_3), plt.axis('off')
plt.subplot(3, 4, 5), plt.imshow(texture, cmap='gray'), plt.axis('off')
plt.subplot(3, 4, 6), plt.imshow(texture1, cmap='gray'), plt.axis('off')
plt.subplot(3, 4, 7), plt.imshow(texture2, cmap='gray'), plt.axis('off')
plt.subplot(3, 4, 8), plt.imshow(texture3, cmap='gray'), plt.axis('off')
plt.subplot(3, 4, 9), plt.plot(bins, textureHist)
plt.subplot(3, 4, 10), plt.plot(bins, textureHist1)
plt.subplot(3, 4, 11), plt.plot(bins, textureHist2)
plt.subplot(3, 4, 12), plt.plot(bins, textureHist3)
plt.show()
![](https://img.haomeiwen.com/i21107801/a3c67c80cb36ff9f.png)
网友评论