001 摄像头拍照+旋转+截取部分+计算棋盘的四个角点坐标+四点定位拉伸

这样,顶上的摄像头即便稍有一些移位或歪斜,也不影响了。

最终得到的是棋盘的规范图,为后续识别做好了准备。

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Imagedef imgCapture(ImageName):print("拍照")#video="http://admin:admin@192.168.1.109:8081/" #cap=cv2.VideoCapture(video)#测试过用手机当ip摄像头了,别的都还好,就是拍照分辨率不能调整,所以还是用usb有线摄像头cap=cv2.VideoCapture(0)    cap.set(3,1920)cap.set(4,1080)#cap.set(10,1)  #亮度参数 感觉其实没什么用i=10while i>0:i=i-1ret, frame = cap.read() cap.release()#time.sleep(3) # 有些时候 USB摄像头不知道为什么拍的一片漆黑 猜测需要略休眠 实测无效frame = rotate_bound(frame, 180) #旋转角度180度cv2.imwrite(ImageName,frame, [int( cv2.IMWRITE_JPEG_QUALITY), 100]) # 默认95#旋转图像的函数
def rotate_bound(image, angle):print("旋转图片")# grab the dimensions of the image and then determine the# center(h, w) = image.shape[:2](cX, cY) = (w // 2, h // 2)# grab the rotation matrix (applying the negative of the# angle to rotate clockwise), then grab the sine and cosine# (i.e., the rotation components of the matrix)M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)cos = np.abs(M[0, 0])sin = np.abs(M[0, 1])# compute the new bounding dimensions of the imagenW = int((h * sin) + (w * cos))nH = int((h * cos) + (w * sin))# adjust the rotation matrix to take into account translationM[0, 2] += (nW / 2) - cXM[1, 2] += (nH / 2) - cY# perform the actual rotation and return the image#return cv2.warpAffine(image, M, (nW, nH))return cv2.warpAffine(image, M, (nW, nH),borderValue=(255,255,255))# 切出矩形棋盘的一系列函数 开始
# 参考 https://blog.csdn.net/sinat_36458870/article/details/78825571def get_image(path):#获取图片img=cv2.imread(path)gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)return img, graydef Gaussian_Blur(gray):# 高斯去噪blurred = cv2.GaussianBlur(gray, (3, 3),0)return blurreddef Sobel_gradient(blurred):# 索比尔算子来计算x、y方向梯度gradX = cv2.Sobel(blurred, ddepth=cv2.CV_32F, dx=1, dy=0)gradY = cv2.Sobel(blurred, ddepth=cv2.CV_32F, dx=0, dy=1)gradient = cv2.subtract(gradX, gradY)gradient = cv2.convertScaleAbs(gradient)return gradX, gradY, gradientdef Thresh_and_blur(gradient):blurred = cv2.GaussianBlur(gradient, (3, 3),0)#(_, thresh) = cv2.threshold(blurred, 90, 255, cv2.THRESH_BINARY)(_, thresh) = cv2.threshold(blurred, 90, 255, cv2.THRESH_BINARY)    return threshdef image_morphology(thresh,juanjihe):  #定义卷积核大小,juanjihe=50可以把棋盘框出来 =20的时候可以用于识别顶点# 建立一个椭圆核函数kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (juanjihe, juanjihe))  #把卷积核大一些 就可以获得整个棋盘 不然太小会只截取一部分# 执行图像形态学, 细节直接查文档,很简单closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)closed = cv2.erode(closed, None, iterations=4)closed = cv2.dilate(closed, None, iterations=4)return closeddef findcnts_and_box_point(closed):# 这里opencv3返回的是三个参数#(_, cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)(cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)  #opencv版本 如果不行就用上面的那个c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]# compute the rotated bounding box of the largest contourrect = cv2.minAreaRect(c)box = np.int0(cv2.boxPoints(rect))return boxdef drawcnts_and_cut(original_img, box):# 因为这个函数有极强的破坏性,所有需要在img.copy()上画# draw a bounding box arounded the detected barcode and display the imagedraw_img = cv2.drawContours(original_img.copy(), [box], -1, (0, 0, 255), 3)Xs = [i[0] for i in box]Ys = [i[1] for i in box]print(Xs)print(Ys)x1 = min(Xs)x2 = max(Xs)y1 = min(Ys)y2 = max(Ys)hight = y2 - y1width = x2 - x1#crop_img = original_img[y1:y1+hight, x1:x1+width]crop_img = original_img[(y1-20):(y1+hight+20), (x1-20):(x1+width+20)]#多切一点儿 切得太准确了 会导致后面角点检测找不到正确的四个角点return draw_img, crop_img# 切出矩形棋盘的一系列函数 结束# 角点检测函数
def jiaodian(image_p):print("进行角点检测")img =cv2.imread(image_p) imgray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#harris角点检测图像需为float32gray=np.float32(imgray)dst=cv2.cornerHarris(gray,4,3,0.04) #如果不准 可以改gray后面那个参数 越改小则检测出来的角点越多dst=cv2.dilate(dst,None)ret,dst=cv2.threshold(dst,0.01*dst.max(),255,0)dst=np.uint8(dst)#图像连通域ret,labels,stats,centroids=cv2.connectedComponentsWithStats(dst)#迭代停止规则criteria=(cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER,100,0.0001)  #如果不准 可以改最后一个参数 越改小则检测出来的角点越多corners=cv2.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria)res=np.hstack((centroids,corners))res=np.int0(res)#print(res)'''#img[res[:,1],res[:,0]]=[0,120,255]#img[res[:,3],res[:,2]]=[45,255,100]for i in res:x1,y1,x2,y2=i.ravel()cv2.circle(img,(x1,y1),3,255,-1)cv2.circle(img,(x2,y2),3,(0,255,0),-1)img=img[:,:,::-1]cv2.imshow('dst',img)if cv2.waitKey(0) & 0xff == 27:cv2.destroyAllWindows()'''return res# 确定四点 矩形拉伸
def img_lashen(img,new_image,x1,y1,x2,y2,x3,y3,x4,y4):print("四点定位拉伸图片")imgages = cv2.imread(img)rows, cols = imgages.shape[:2]# 原图 四个角点'''x1 = 746y1 = 243x2 = 1374y2 = 230x3 = 752y3 = 866x4 = 1384y4 = 863'''x2x1 = (x2-x1)/9x4x3 = (x4-x3)/9y3y1 = (y3-y1)/10y4y2 = (y4-y2)/10x1new = x1 - x2x1y1new = y1 - y3y1x2new = x2 + x2x1y2new = y2 - y4y2x3new = x3 - x4x3y3new = y3 + y3y1x4new = x4 + x4x3y4new = y4 + y4y2#pts1 = np.float32([[628, 36], [1426, 177], [600, 1055], [1394, 947]])pts1 = np.float32([[x1new, y1new], [x2new, y2new], [x3new, y3new], [x4new, y4new]])# 变换后分别在左上、右上、左下、右下四个点#pts2 = np.float32([[628, 36], [1426, 36], [628, 1055], [1426, 1055]])#pts2 = np.float32([[0, 0], [900, 0], [0, 1000], [900, 1000]])pts2 = np.float32([[0, 0], [1100, 0], [0, 1200], [1100, 1200]])# 生成透视变换矩阵M = cv2.getPerspectiveTransform(pts1, pts2)# 进行透视变换dst = cv2.warpPerspective(imgages, M, (1100, 1200))#plt.subplot(121), plt.imshow(imgages[:, :, ::-1]), plt.title('b.png')#plt.subplot(122), plt.imshow(dst[:, :, ::-1]), plt.title('c.png')# imgages[:, :, ::-1]是将BGR转化为RGB#plt.show()cv2.imwrite(new_image, dst)MyImageName = 'a.png'
My_new_image = 'b.png'
My_last_image = 'c.png'imgCapture(MyImageName)#img0 = cv2.imread(MyImageName)
#plt.imshow(img0),plt.show()print("切出矩形棋盘")
# 切出矩形棋盘
img_path = MyImageName
save_path = My_new_image
original_img, gray = get_image(img_path)
blurred = Gaussian_Blur(gray)
gradX, gradY, gradient = Sobel_gradient(blurred)
thresh = Thresh_and_blur(gradient)
closed = image_morphology(thresh,50) #50可以识别出棋盘
box = findcnts_and_box_point(closed)
draw_img, crop_img = drawcnts_and_cut(original_img,box)
cv2.imwrite(save_path, crop_img)# 截成四个象限 用于分别计算最远角点 以便使棋盘拉伸更精确
imgb = Image.open(My_new_image)
imgb_size = imgb.size
hb = imgb_size[1]  # 图片高度
wb = imgb_size[0]  # 图片宽度
regionb1 = imgb.crop((0, 0, (wb/2), (hb/2)))
regionb2 = imgb.crop(((wb/2), 0, wb, (hb/2)))
regionb3 = imgb.crop((0, (hb/2), (wb/2), hb))
regionb4 = imgb.crop(((wb/2), (hb/2), wb, hb))
# 保存图片
regionb1.save("b_1.png")
regionb2.save("b_2.png")
regionb3.save("b_3.png")
regionb4.save("b_4.png")# 切出之后 进行角点查找# image_p1
px = wb/2
py = hb/2
res = jiaodian('b_1.png')
x_max = 0
y_max = 0
z_max = 0 #面积
for i in res:x1,y1,x2,y2=i.ravel()lx = abs(px - x1)ly = abs(py - y1)z = lx*lyif z > z_max:x_max = x1y_max = y1z_max = z
tx1 = x_max
ty1 = y_max
print(tx1,ty1)# image_p2
px = 0
py = hb/2
res = jiaodian('b_2.png')
x_max = 0
y_max = 0
z_max = 0 #面积
for i in res:x1,y1,x2,y2=i.ravel()lx = abs(px - x1)ly = abs(py - y1)z = lx*lyif z > z_max:x_max = x1y_max = y1z_max = z
tx2 = x_max+(wb/2)
ty2 = y_max
print(tx2,ty2)# image_p3
px = wb/2
py = 0
res = jiaodian('b_3.png')
x_max = 0
y_max = 0
z_max = 0 #面积
for i in res:x1,y1,x2,y2=i.ravel()lx = abs(px - x1)ly = abs(py - y1)z = lx*lyif z > z_max:x_max = x1y_max = y1z_max = z
tx3 = x_max
ty3 = y_max+(hb/2)
print(tx3,ty3)# image_p4
px = 0
py = 0
res = jiaodian('b_4.png')
x_max = 0
y_max = 0
z_max = 0 #面积
for i in res:x1,y1,x2,y2=i.ravel()lx = abs(px - x1)ly = abs(py - y1)z = lx*lyif z > z_max:x_max = x1y_max = y1z_max = z
tx4 = x_max+(wb/2)
ty4 = y_max+(hb/2)
print(tx4,ty4)#拉伸
print("根据四点拉伸图片")
img_lashen(My_new_image,My_last_image,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4) # 显示一下 原照片a 截取的区域b 最终拉伸成为规范矩形的c
plt.figure()
plt.subplot(1,3,1)      # 将画板分为1行3列,本幅图位于第1个位置
imga = plt.imread('a.png')
plt.imshow(imga)
plt.subplot(1,3,2)      # 将画板分为1行3列,本幅图位于第2个位置
imgb = plt.imread('b.png')
plt.imshow(imgb)
plt.subplot(1,3,3)      # 将画板分为1行3列,本幅图位于第3个位置
imgc = plt.imread('c.png')
plt.imshow(imgc)
plt.show()

001 摄像头拍照+旋转+截取部分+计算棋盘的四个角点坐标+四点定位拉伸相关推荐

  1. C++/Qt 使用OpenCV打开摄像头,旋转视频,计算fps

    C++/Qt 使用OpenCV打开摄像头,旋转视频,计算fps 设置摄像头参数 不要随意修改,同时也不一样会修改成功,需要根据实际摄像头的参数选择设置 /*设置摄像头参数 不要随意修改capture. ...

  2. input调起ios摄像头拍照旋转问题解决思路

    背景 input标签调起ios原生摄像头拍照时,上传照片发现照片向左旋转了90度 旋转的原因: 手机拍照会给图片添加一个Orientaion信息(即拍照方向),如下: 用ios手机拍照,系统会给图片加 ...

  3. vue实现PC端调用摄像头拍照人脸录入、移动端调用手机前置摄像头人脸录入、及图片旋转矫正、压缩上传base64格式/文件格式

    PC端调用摄像头拍照上传base64格式到后台,这个没什么花里胡哨的骚操作,直接看代码 (canvas + video) <template><div><!--开启摄像头 ...

  4. iPhone摄像头拍照后图像旋转

    最近做了个有关图像处理的APP,里面涉及到拍照和从相册读图,测试时发现一个神奇的问题. 当我用后置摄像头拍照,然后将拍摄到的图片显示在APP界面上时,图片一切正常,然后读取图片像素信息,再用像素信息生 ...

  5. vue移动端页面调用手机拍照_vue实现PC端调用摄像头拍照、移动端调用手机前置摄像头人脸录入、及图片旋转矫正、压缩上传base64格式/文件格式...

    export default { () { return {} }, methods: { # // 压缩图片 and 旋转角度纠正 下方代码 # 需要自行去掉 个人只作为着色效果加上 compres ...

  6. 怎么用计算机上摄像头拍照,win7电脑怎么用摄像头拍照?win7电脑用摄像头拍照的详细步骤...

    现在电脑都自带有摄像头功能,那么就可以拍照了.在win7电脑中即使安装摄像头之后,在电脑中也看不到它的图标或者快捷方式.那么win7电脑怎么用摄像头拍照?大家可以尝试把摄像头程序的快捷方式放到&quo ...

  7. 怎么用计算机上摄像头拍照,用电脑上的摄像头拍照的方法步骤

    现在很多人都喜欢用电脑摄像头进行视频通话,但其实不仅仅可以使用摄像头进行视频,还能用来拍照喔,下面是学习啦小编整理的电脑照相的方法,供您参考. 电脑照相的方法 右击桌面"计算机"( ...

  8. js调用本地摄像头拍照截图,提交后台

    今天有个需求,需要在前端界面调用本地摄像头,然后拍照结束后可以截取预览,最后将结果提交到后台.查了网上很多的插件,发现适合的非常少,于是决定自己修改一个. 这里我修改了一个jquery插件,把摄像头拍 ...

  9. java jmf 视屏监控的核心代码_Java中利用JMF编写摄像头拍照程序_java

    我把程序分为两种,有趣的和无趣的,最近做了几个有趣的项目,其中一个,应当就算是摄像头拍照程序了.用于现场拍照,生成照片,主要用到java Media Framework(JMF). 首先到SUN下载最 ...

最新文章

  1. 【NLP】Word2Vec详解(含数学推导)
  2. centos7.6查询不到网卡信息
  3. java编程double相乘_浅谈Java double 相乘的结果偏差小问题
  4. .NET 6 新特性 Parallel ForEachAsync
  5. Loj#143-[模板]质数判定【Miller-Rabin】
  6. live2dviewer android,live2dviewerex安卓版
  7. superset ubuntu16.04 python3 安装
  8. android错误怎么关机,Android系统小技巧:系统崩溃了只重启部分子系统,而不是全部重启...
  9. 英语中比较重要的动词
  10. 编程语言Python为什么这么火?
  11. 电子DIY:用单片机设计一款USB游戏手柄
  12. word中鼠标拖动文字突然无法突出显示
  13. 【转】objective-c基本数据类型之输出格式符
  14. 开发一款游戏需要怎么做
  15. 坚持就是胜利,坚持就是升华
  16. python 批量爬取网易云音乐,java解密
  17. 安卓系统刷机怎么刷机_安卓系统手机怎么刷机
  18. 12306 订票助手 C# 版
  19. java反射详解---具体代码操作看看反射都能干些什么
  20. 获取地址eth,usdt 余额及最早一次交易记录

热门文章

  1. 拱猪java_模拟——拱猪积分题解
  2. 2023年华为HCIE-Datacom认证(H12-891、H12-892)
  3. Windows系统局域网共享磁盘、共享文件方法
  4. linux mac time machine,树莓派、Windows 设备都可以做你 Mac 的「时间机器」——利用 SMB 协议进行 Time Machine 备份...
  5. 千橡互动宣布推出团购网站tao66
  6. C# 编写简单易用的 Windows 截屏增强工具
  7. Azure Kinect DK
  8. 宝塔sh实现30秒运行一次脚本
  9. 【Java】pageHelper实现分页
  10. 游戏运营环节的一些关键转化率