opencv基础知识及其一些例子

opencv官网

一.插值法

1.最近邻插值

上图可看出f(p)=f(Q11),缺点可能出现明显的块状。

2.线性插值

3.双线性插值

通过线性插值确定R1和R2,最终在确定P

二.cv2.putText 图片添加文字

import cv2
img = cv2.imread('caijian.jpg')
font = cv2.FONT_HERSHEY_SIMPLEXimgzi = cv2.putText(img, '000', (50, 300), font, 1.2, (255, 255, 255), 2)

三.求凸包 

import cv2
import matplotlib.pyplot as plt
import numpy as np
import scipy
from scipy.spatial import ConvexHull
##########scipy 凸包################
c = np.random.rand(5, 2)
print(c)
hull = ConvexHull(c)
# print(hull)
plt.plot(c[:,0], c[:,1], 'o')
# hull.vertices 得到凸轮廓坐标的索引值,逆时针画
hull_1=hull.vertices.tolist()#要闭合必须再回到起点[0]
print(hull_1)# hull_1.append(hull_1[0])
print(hull_1)
plt.plot(c[hull_1,0], c[hull_1,1])
plt.show()

hull_1.append(hull_1[0])这句话的作用就是要形成一个闭环。

打印结果中的4,0,2,1代表的是索引值

四.fit一条直线,可用来做轮廓旋转

path = './data/sichuan_pig_mistake_label/2018-9-14IMG_8057.JPG'
image=cv2.imread(path,cv2.IMREAD_GRAYSCALE)
img_size = cv2.resize(image, (500, 300))height, width = img_size.shape[:2]
image_thre = cv2.threshold(img_size, 127, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(image_thre, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
c = sorted(cnts, key=cv2.contourArea, reverse=True)
c = np.squeeze(c[0])
plt.plot(c[:, 0], c[:, 1])#vy/vx代表斜率  x, y是直线上的任意一点
[vx, vy, x, y] = cv2.fitLine(c, cv2.DIST_L2, 0, 0.01, 0.01)
#y=k*x+b  b=-k*x1+y1
b = int((-x * vy / vx) + y)
#y=k*(cols-1)+b=(cols-1-x1)*k+y1
righty = int(((width- 1-x) * vy / vx) + y)plt.plot((0,width-1),(b,righty))
plt.show()

五.找出轮廓内的所有点

cv2.drawContours()函数

cv2.drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset)  

  • 第一个参数是指明在哪幅图像上绘制轮廓;
  • 第二个参数是轮廓本身,在Python中是一个list。
  • 第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。thickness表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。
path = './data/sichuan_pig_mistake_label/2018-9-14IMG_9811.JPG'
img=cv2.imread(path,cv2.IMREAD_GRAYSCALE)
# 二值化找轮廓
image_thre = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(image_thre, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = cnts[0] if imutils.is_cv2() else cnts[1]
c_ = sorted(contours, key=cv2.contourArea, reverse=True)
pig_cnt = np.squeeze(c_[0])image_h=img.shape[0]
image_w = img.shape[1]
mask = np.zeros((image_h, image_w, 3))
plt.plot(pig_cnt[:, 0], pig_cnt[:, 1])
plt.show()
dummy_mask = cv2.drawContours(mask, [pig_cnt], 0, (255, 0, 0), thickness=cv2.FILLED)
y, x = np.where(dummy_mask[:, :, 0] == 255)
inside_points = np.stack((x, y), axis=-1)
plt.plot(inside_points[:, 0], inside_points[:, 1], 'o')
plt.show()

六.cv2.fillPoly填充轮廓区域

cv2.fillPoly(img, pts, color, lineType=None, shift=None, offset=None)  pts.shape:(4,2)

1.示例1

import cv2
import numpy as np
black = np.zeros((10, 10))
contour = np.array([[1, 1],[5, 1],[5, 5],[1, 5]])
img = cv2.fillPoly(black, [contour], color=(255, 255, 255))
print(img)
print(img.shape)
cv2.imwrite('./img.jpg', img)

2.示例2 

import numpy as np
import cv2
import jsonjson_path = './1.json'
path ='./1.jpg'
img = cv2.imread(path).astype(np.uint8)
h, w, _ = img.shapeblack = np.zeros((h, w, 3)).astype(np.uint8)
with open(json_path) as file:json_info = json.load(file)
# print(json_info)
for shape in json_info['shapes']:label = shape['label']points = shape['points']contour = np.array(points).astype(np.int32)# print(contour.shape)# cv2.fillPoly(img, [contour], (255, 0, 0))random_b = int(np.random.randint(0, 200, 1)[0])random_g = int(np.random.randint(0, 255, 1)[0])random_r = int(np.random.randint(100, 255, 1)[0])color = (random_b, random_g, random_r)cv2.fillPoly(black, [contour], color)
dummy_mask = cv2.addWeighted(img, 1., black, 0.6, 0)
# cv2.fillConvexPoly(img, contour, 1)
cv2.imwrite('./dummy_mask.jpg', dummy_mask)

七. 图片与视频之间转换

1.测试摄像头视频

import cv2
import numpy as npcap = cv2.VideoCapture("./test.avi")
while(1):# get a frameret, frame = cap.read()# show a framecv2.imshow("capture", frame)if cv2.waitKey(100) & 0xFF == ord('q'):break
cap.release()
cv2.destroyAllWindows()

2.摄像头读完存储为本地视频

import cv2
import numpy as np#未进行亮度增强的原始视频
def test_original_video():cap = cv2.VideoCapture(0)cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)#设定宽度cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)#设定高度fourcc = cv2.VideoWriter_fourcc(*'XVID')out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))#fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')#if os.path.exists('./output.mp4'):#    os.remove('./output.mp4')#out = cv2.VideoWriter('./output.mp4', fourcc, time_interval, (img_w, img_h))while cap.isOpened():frame_index = 0# get a frameisSuccess, frame = cap.read()if frame is not None:# show a frameout.write(frame) #写入本地cv2.imshow("capture", frame)#todo 写发送给后端程序if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()out.release()cv2.destroyAllWindows()if __name__ == '__main__':test_original_video()

3.图片转视频 

# 图片转视频
def jpg_video():""" 将图片合成视频. sp: 视频路径,fps: 帧率 """image_path = './image_mask_low_clear'images_list_path=[os.path.join(image_path,i) for i in os.listdir(image_path)]images_list_path=sorted(images_list_path,key=lambda x:int(x.split('/')[-1].split('.')[0]))print(images_list_path)h,w,_=cv2.imread(images_list_path[0]).shapefps=4fourcc = cv2.VideoWriter_fourcc(*'MJPG')videoWriter = cv2.VideoWriter('predict_low_clear.avi', fourcc, fps, (w, h))  # 最后一个是保存图片的尺寸for i,image_list_path in enumerate(images_list_path):frame = cv2.imread(image_list_path)videoWriter.write(frame)videoWriter.release()

4.视频转图片

# coding=utf-8
import cv2
import os
path='./data'
dirs_name_path=[os.path.join(path,i) for i in os.listdir(path)]
print(dirs_name_path)videos_src_path = "./data/videos"
# video_formats = [".MP4", ".MOV"]          我的数据集都是.mp4所以不需要进行分类判断
frames_save_path = "./data/images/"
# if not os.mkdir(frames_save_path):
#     os.mkdir(frames_save_path)
time_interval = 5def video2frame(video_src_path,frame_save_path,interval):"""将视频按固定间隔读取写入图片:param video_src_path: 视频存放路径:param formats: 包含的所有视频格式:param frame_save_path: 保存路径:param frame_width: 保存帧宽:param frame_height: 保存帧高:param interval: 保存帧间隔:return: 帧图片"""videos = os.listdir(video_src_path)for each_video in videos:# print "正在读取视频:", each_videoprint("正在读取视频:", each_video)    # 我的是Python3.6each_video_name = each_video[:-4]print(each_video_name)os.mkdir(frame_save_path + each_video_name)each_video_save_full_path = os.path.join(frame_save_path, each_video_name) + "/"each_video_full_path = os.path.join(video_src_path, each_video)cap = cv2.VideoCapture(each_video_full_path)frame_index = 0frame_count = 0if cap.isOpened():success = Trueelse:success = Falseprint("读取失败!")while(success):success, frame = cap.read()print("---> 正在读取第%d帧:" % frame_index, success)      # 我的是Python3.6if frame_index % interval == 0 and success:     # 如路径下有多个视频文件时视频最后一帧报错因此条件语句中加and success# resize_frame = cv2.resize(frame, (frame_width, frame_height), interpolation=cv2.INTER_AREA)cv2.imwrite(each_video_save_full_path + "%d.png" % frame_count, frame)frame_count += 1frame_index += 1cap.release()def main():video2frame(videos_src_path,frames_save_path,time_interval)
if __name__ == '__main__':main()

八.cv2.polylines画多边形 给定的点必须是顺时针

path = './134.jpg'img = cv2.imread(path)print(img.shape)line1 = [728, 252, 908, 215, 934, 312, 752, 355]  # 四边形四个点坐标的一维数组表示,[x,y,x,y....]line2 = [741, 262, 907, 228, 923, 308, 758, 342]#debug to showline1 = np.array(line1).reshape(4, 2)line2 = np.array(line2).reshape(4, 2)cv2.polylines(img, [np.array(line1).reshape(-1, 1, 2)], True, (0, 255, 0), thickness=5)cv2.polylines(img, [np.array(line2).reshape(-1, 1, 2)], True, (0, 0, 255), thickness=5)cv2.imwrite('134_with_rect.jpg',img)

九.迪卡尔坐标和极坐标之间的转换  cv2.cartToPolar,cv2.polarToCart

(1)函数示例

#测试极坐标变换
def test_polar():# x1 = r*cos0# y1 = r*sin0x = np.array([0, 1, 2], np.float64)y = np.array([0, 1, 4], np.float64)#迪卡尔转极坐标r, theta = cv2.cartToPolar(x, y, angleInDegrees=True)print("===从迪卡尔坐标转换为极坐标===")print('r:', r)print('theta:', theta)# 极坐标转迪卡尔x1, y1 = cv2.polarToCart(r, theta, angleInDegrees=True)print("===从极坐标转换为迪卡尔坐标===")print('x1:', x1)print('y1:', y1)

(2)运用

#coding:utf-8
import cv2
import numpy as npdef polar(img, center, r, theta=(0, 360), rstep=1.0, thetastep = 360.0/(180*8)):# 图像灰度处理gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 得到距离的最小、最大范围minr, maxr = rprint('r:', r)#角度的最小范围mintheta, maxtheta = thetaprint('mintheta, maxtheta', mintheta, maxtheta)# 输出图像的高、宽H = int((maxr-minr)/rstep)+1W = int((maxtheta-mintheta)/thetastep)+1O = 125 * np.ones((H, W), gray.dtype)print('H:', H)print('W:', W)# print('O.shape:', O.shape)# 极坐标变换r = np.linspace(minr, maxr, H)# print('r.shape:', r.shape)r = np.tile(r, (W, 1))# print('r.shape:', r.shape)r = np.transpose(r)print('r.shape:', r.shape)theta = np.linspace(mintheta, maxtheta, W)theta = np.tile(theta, (H, 1))x, y = cv2.polarToCart(r, theta, angleInDegrees=True)print('theta.shape:', theta.shape)# 最近邻插值for i in range(H):for j in range(W):px = int(round(x[i][j]) + cx)py = int(round(y[i][j]) + cy)if((px>=0 and px<=w-1)and (py>=0 and py<=h-1)):O[i][j] = gray[py][px]return Oif __name__ == '__main__':print("---------------Hello python ------------")filename = ("disk.png")img = cv2.imread(filename)# 图像的宽、高h, w = img.shape[:2]# 极坐标中心cx, cy = w/2, h/2# 标出图像中心点cv2.circle(img, (int(cx), int(cy)), 10, (255, 0, 0), 3)out = polar(img, (cx, cy), (0, w/2))out = out[::-1, ...]cv2.imwrite('out.jpg', out)

变为

十.利用cv2.inRange选择ROI hsv截图ROI

  src = cv2.imread('./flower.png')# 生成mask区域hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)mask = cv2.inRange(hsv, (156, 43, 46), (180, 255, 255))print('mask.shape:', mask.shape)cv2.imwrite('mask.jpg', mask)mask = np.concatenate((np.expand_dims(mask,-1),np.expand_dims(mask,-1),np.expand_dims(mask,-1)),axis=-1)# 提取ROI区域,根据mask# result = cv2.bitwise_and(src, src, mask=mask)result = mask/255*srccv2.imwrite('result.jpg', result)

十一.cv2.bitwise_and 用来做与操作,可以过滤噪声, cv2.getStructuringElement定义卷积核形式

1.案例1

img = cv2.imread('./table_crop_bin_.jpg')img_bin = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)mask_= cv2.imread('./mask.jpg')mask = cv2.cvtColor(mask_, cv2.COLOR_BGR2GRAY)mask[mask < 127] = 0img_bin_ = cv2.bitwise_and(img_bin, img_bin, mask=mask)cv2.imwrite('./img_bin_after_mask.jpg',img_bin_)

img_bin:

mask:

after_mask:

2.案例2 cv2.getStructuringElement定义十字卷积核,再膨胀这样只对线变粗

img = cv2.imread('./table_crop.jpg')
cv_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化
img_bin = cv2.adaptiveThreshold(cv_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
img_bin = 255 - img_bin  # Invert the image# 二次消除小轮廓
# image, contours, hierarchy = cv2.findContours(img_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)#opencv3
contours, _ = cv2.findContours(img_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)#opencv4
mask = np.ones(img.shape[:2], dtype="uint8") * 255
th_w = img_bin.shape[1]/30
th_h = img_bin.shape[0]/30
for c in contours:x, y, w, h = cv2.boundingRect(c) #第一遍根据长宽删选if w < th_w and h < th_h:cv2.drawContours(mask, [c], -1, 0, -1)
# cv2.imwrite('./mask.jpg', mask)
img_bin = cv2.bitwise_and(img_bin, img_bin, mask=mask)img_bin_ = ~img_bin
cv2.imwrite('./img_bin_no_noise.jpg', img_bin_)kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
img_bin = cv2.dilate(img_bin, kernel, iterations=1)
cv2.imwrite('./img_bin_dilate.jpg', img_bin)

3.案例3用来去除背景


import cv2
import numpy as np
path = './test_threshold.png'
img = cv2.imread(path)
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
#自适应二值化
threshold = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,25,15)
# cv2.imwrite('./threshold.jpg', threshold)
#形态学操作进行膨胀
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
mask = cv2.dilate(threshold, kernel)
# cv2.imwrite('./mask.jpg', mask)
#背景为白色的黑色字
mask1 = cv2.bitwise_not(mask)
# cv2.imwrite('./mask1.jpg', mask1)
#扣出文字,此时背景为黑色
mask_img = cv2.bitwise_and(gray, mask)
# cv2.imwrite('./mask_img.jpg', mask_img)
#融合得出去除背景的图
fin_mask_img = cv2.add(mask_img, mask1)
cv2.imwrite('./fin_mask_img.jpg', fin_mask_img)

原图 去完背景图

十二.一些非线性变换,主要用于图像增强

1.图像灰度非线性变换:DB=DA×DA/255,灰色会变成黑色

#coding:utf-8
import numpy as np
import cv2
import matplotlib.pyplot as plt#原始图像的灰度值按照DB = DA×DA / 255的公式进行非线性变换,使灰色的变成黑色
def non_linear_transform():path = './test_gamma.png'img = cv2.imread(path)# print('==img.shape:', img.shape)gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)h, w = gray_img.shape# cv2.imwrite('./gray_img.jpg', gray_img)temp_img = gray_img.copy().astype(np.float32)print(temp_img.dtype)# cv2.imwrite('./temp_img.jpg', temp_img)out_img = np.clip((temp_img*temp_img)/255, 0, 255)cv2.imwrite('./out_img.jpg', out_img)

   

2.图像灰度对数变换

公式:

由于对数曲线在像素值较低的区域斜率大,在像素值较高的区域斜率较小,所以图像经过对数变换后,较暗区域的对比度将有所提升。可用于增强图像的暗部细节.

#图像灰度的对数变换--Db=c*log(1+Da)
#对数变换对于整体对比度偏低并且灰度值偏低的图像增强效果较好。
def log_transform():x = np.arange(0, 256, 0.01)c = 1.y = c*np.log(1+x)#以e为底plt.plot(x, y, 'r', linewidth='1')plt.rcParams['font.sans-serif'] = ['SimHei'] #正常显示中文标签plt.title(u'对数变换')plt.xlim(0, 255)plt.ylim(0, 6)plt.show()path = './log_tr.png'img = cv2.imread(path).astype(np.float32)c = 42.out = c * np.log(1 + img)  # 以e为底out = np.clip(out+0.5, 0, 255).astype(np.uint8)cv2.imwrite('./out_log.jpg', out)

3.图像灰度伽玛变换

公式:

伽马变换对于图像对比度偏低,并且整体亮度值偏高(或由于相机过曝)情况下的图像增强效果明显

#gamma变换Db=c*Da^gamma
#当gamma>1时,会拉伸图像中灰度级较高的区域,压缩灰度级较低的部分。
#当gamma<1时,会拉伸图像中灰度级较低的区域,压缩灰度级较高的部分。
#当gamma=1时,该灰度变换是线性的,此时通过线性方式改变原图像。
#适用于解决曝光过度的问题
def gamma_transform():path = './gamma_test.png'img = cv2.imread(path).astype(np.float32)c = 0.00000005gamma = 4.0out = c*img**gammaout = np.clip(out, 0, 255)cv2.imwrite('./out_gamma.jpg', out)

  

十三-1:cv2.warpAffine()仿射变换函数

例1.可实现旋转,平移,缩放;变换后的平行线依旧平行,用于图像预处理

import cv2img = cv2.imread('./20210829110603899.png', 0)
h, w = img.shape
new_h = 1000
new_w = 600
scale = min(new_h / h, new_w / w)
print(new_h / h, new_w / w)
factor = np.array([[scale, 0, 0],[0, scale, 0]])
new_img = cv2.warpAffine(img, factor, (new_w, new_h), borderValue=127)
print(new_img.shape)
cv2.imwrite('./new_img1.jpg', new_img)factor = np.array([[scale, 0, new_w / 2 - scale * w / 2],[0, scale, new_h / 2 - scale * h / 2]])
new_img = cv2.warpAffine(img, factor, (new_w, new_h), borderValue=127)
print(new_img.shape)
cv2.imwrite('./new_img2.jpg', new_img)

例2.通过原始点与目标点计算仿射矩阵,变换图像与关键点

import numpy as np
import cv2def get_affine_transform(center,scale,rot,output_size,shift=(0., 0.),inv=False):"""Get the affine transform matrix, given the center/scale/rot/output_size.Args:center (np.ndarray[2, ]): Center of the bounding box (x, y).scale (np.ndarray[2, ]): Scale of the bounding boxwrt [width, height].rot (float): Rotation angle (degree).output_size (np.ndarray[2, ] | list(2,)): Size of thedestination heatmaps.shift (0-100%): Shift translation ratio wrt the width/height.Default (0., 0.).inv (bool): Option to inverse the affine transform direction.(inv=False: src->dst or inv=True: dst->src)Returns:np.ndarray: The transform matrix."""assert len(center) == 2assert len(scale) == 2assert len(output_size) == 2assert len(shift) == 2# pixel_std is 200.scale_tmp = scale * 200.0shift = np.array(shift)src_w = scale_tmp[0]dst_w = output_size[0]dst_h = output_size[1]rot_rad = np.pi * rot / 180src_dir = rotate_point([0., src_w * -0.5], rot_rad)dst_dir = np.array([0., dst_w * -0.5])print('=center:', center)print('==scale_tmp:', scale_tmp)print('==:shift:', shift)print('=src_dir:', src_dir)src = np.zeros((3, 2), dtype=np.float32)src[0, :] = center + scale_tmp * shiftsrc[1, :] = center + src_dir + scale_tmp * shiftsrc[2, :] = _get_3rd_point(src[0, :], src[1, :])print('===src:', src)dst = np.zeros((3, 2), dtype=np.float32)dst[0, :] = [dst_w * 0.5, dst_h * 0.5]dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5]) + dst_dirdst[2, :] = _get_3rd_point(dst[0, :], dst[1, :])print('===dst:', dst)if inv:trans = cv2.getAffineTransform(np.float32(dst), np.float32(src))else:trans = cv2.getAffineTransform(np.float32(src), np.float32(dst))return trans, src, dstdef _get_3rd_point(a, b):"""To calculate the affine matrix, three pairs of points are required. Thisfunction is used to get the 3rd point, given 2D points a & b.The 3rd point is defined by rotating vector `a - b` by 90 degreesanticlockwise, using b as the rotation center.Args:a (np.ndarray): point(x,y)b (np.ndarray): point(x,y)Returns:np.ndarray: The 3rd point."""assert len(a) == 2assert len(b) == 2direction = a - bthird_pt = b + np.array([-direction[1], direction[0]], dtype=np.float32)return third_ptdef rotate_point(pt, angle_rad):"""Rotate a point by an angle.Args:pt (list[float]): 2 dimensional point to be rotatedangle_rad (float): rotation angle by radianReturns:list[float]: Rotated point."""assert len(pt) == 2sn, cs = np.sin(angle_rad), np.cos(angle_rad)new_x = pt[0] * cs - pt[1] * snnew_y = pt[0] * sn + pt[1] * csrotated_pt = [new_x, new_y]return rotated_ptdef affine_transform(pt, trans_mat):"""Apply an affine transformation to the points.Args:pt (np.ndarray): a 2 dimensional point to be transformedtrans_mat (np.ndarray): 2x3 matrix of an affine transformReturns:np.ndarray: Transformed points."""assert len(pt) == 2new_pt = np.array(trans_mat) @ np.array([pt[0], pt[1], 1.])return new_ptc = np.array([176.23245, 235.00899], dtype=np.float)
s = np.array([1.676609, 1.676609], dtype=np.float32)
r = 0
image_size = [256, 256]
img1 = cv2.imread('./hand_img.jpg')trans, src, dst = get_affine_transform(c, s, r, image_size)#获取仿射变换矩阵# assert 1 == 0
#对原始图片进行仿射变换,获取需要的256*256图片
img2 = cv2.warpAffine(img1,trans, (int(image_size[0]), int(image_size[1])),flags=cv2.INTER_LINEAR)joint_3d = np.array([[ 179.5004   ,  155.19913  ,  -28.959717 ],[ 204.43983  ,  181.01262  ,  -27.860962 ],[ 238.99097  ,  203.22014  ,  -24.98816  ],[ 258.56006  ,  247.28287  ,  -22.415161 ],[  82.02937  ,  208.90874  ,   15.491821 ],[ 108.736206 ,  211.6331   ,   12.446289 ],[ 138.15198  ,  214.90436  ,   12.52124  ],[ 187.65051  ,  224.30232  ,    5.1589355],[  64.458534 ,  238.55043  ,   22.159302 ],[  92.78469  ,  239.35489  ,   19.358276 ],[ 129.30128  ,  241.59935  ,   21.450684 ],[ 184.5111   ,  248.95364  ,   16.177368 ],[  74.88563  ,  269.69592  ,   24.958252 ],[ 102.517715 ,  269.61853  ,   22.434326 ],[ 137.18251  ,  269.18402  ,   24.199707 ],[ 186.39644  ,  272.3858   ,   18.314575 ],[ 109.839554 ,  314.81885  ,   34.159058 ],[ 132.8085   ,  308.8698   ,   28.636108 ],[ 156.04227  ,  302.9549   ,   25.372803 ],[ 193.64702  ,  295.3736   ,   17.579102 ],[ 288.0064   ,  272.3743   ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ],[-644.62415  ,   38.12097  ,    0.       ]], dtype=np.float32)print('==trans:', trans)
for point in src:cv2.circle(img1, tuple(point.astype(np.int)), radius=2, color=(0, 0, 255), thickness=2)
for point in joint_3d:cv2.circle(img1, tuple(point[:2].astype(np.int)), radius=2, color=(255, 0, 0), thickness=2)
cv2.imwrite('./hand_img_draw.jpg', img1)for i in range(len(joint_3d)):joint_3d[i, 0:2] = affine_transform(joint_3d[i, 0:2], trans)print('==trans:', trans)
for point in dst:cv2.circle(img2, tuple(point.astype(np.int)), radius=2, color=(0, 0, 255), thickness=2)
for point in joint_3d:cv2.circle(img2, tuple(point[:2].astype(np.int)), radius=2, color=(255, 0, 0), thickness=2)
cv2.imwrite('./hand_img_affine_draw.jpg', img2)

 

 

十三-2.透视变换cv2.getPerspectiveTransform

可保持直线不变形,但是平行线可能不再平行

点的还原 

pts1 = np.float32([[0, 1], [2, 0], [3, 1], [1, 2]])
pts2 = np.float32([[0, 0], [4, 0], [4, 2], [0, 2]])M = cv2.getPerspectiveTransform(pts1, pts2)
print('===放射矩阵为M:', M)ones = np.ones((4, 1))
tmp = np.concatenate([pts2, ones], axis=-1)
print('==tmp:', tmp)
I = np.matrix(M).I#求逆矩阵
pts1_reduction = np.matmul(I, tmp.transpose(1, 0)).transpose(1, 0)
print('==pts1_reduction:', pts1_reduction)
print(pts1_reduction[:, :2])

根据box的长宽对图片进行不同的透视变换:

    def crop_image_by_bbox(self, image, box):w = (int)(np.linalg.norm(box[0] - box[1]))h = (int)(np.linalg.norm(box[0] - box[3]))width = wheight = hif h > w * 1.5:width = hheight = wM = cv2.getPerspectiveTransform(np.float32(box),np.float32(np.array([[width, 0], [width, height], [0, height], [0, 0]])))else:M = cv2.getPerspectiveTransform(np.float32(box),np.float32(np.array([[0, 0], [width, 0], [width, height], [0, height]])))warped = cv2.warpPerspective(image, M, (width, height))return warped, M#例子:
box = np.array([[1, 2],[3, 4],[5, 6],[7, 8]])

十四.cv2.applyColorMap生成伪彩色

path = './bgr_region_scores.jpg'
img = cv2.imread(path)
img_color = cv2.applyColorMap(np.uint8(img), cv2.COLORMAP_JET)
cv2.imwrite('./img_color.jpg', img_color)

十五.裁剪斜矩形框

方式1:思路:通过计算box的旋转角度,旋转图像和计算旋转后的box在进行裁剪

#coding:utf-8
import cv2
from math import *
import numpy as np
import time, math
import os
import re'''旋转图像并剪裁'''
def rotate(img, points, rotateImagePath, clipImagePath):pt1, pt2, pt3, pt4 = pointsprint('==旋转前pt1,pt2,pt3,pt4:', pt1, pt2, pt3, pt4)withRect = math.sqrt((pt4[0] - pt1[0]) ** 2 + (pt4[1] - pt1[1]) ** 2)  # 矩形框的宽度heightRect = math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)print('==withRect, heightRect:', withRect, heightRect)angle = acos((pt4[0] - pt1[0]) / withRect) * (180 / math.pi)  # 矩形框旋转角度print('==angle:', angle)if pt4[1] > pt1[1]:print("相比原图水平线顺时针旋转")else:print("相比原图水平线逆时针旋转")angle = -angleheight = img.shape[0]  # 原始图像高度width = img.shape[1]  # 原始图像宽度rotateMat = cv2.getRotationMatrix2D((width / 2, height / 2), angle, 1)  # 按angle角度旋转图像heightNew = int(width * fabs(sin(radians(angle))) + height * fabs(cos(radians(angle))))widthNew = int(height * fabs(sin(radians(angle))) + width * fabs(cos(radians(angle))))rotateMat[0, 2] += (widthNew - width) / 2rotateMat[1, 2] += (heightNew - height) / 2imgRotation = cv2.warpAffine(img, rotateMat, (widthNew, heightNew), borderValue=(255, 255, 255))print('==旋转矩阵:', rotateMat.shape)print('==旋转前pt1,pt2,pt3,pt4:', pt1, pt2, pt3, pt4)# 旋转后图像的四点坐标# pt1_rotate = np.dot(rotateMat, np.array([[pt1[0]], [pt1[1]], [1]]))# pt2_rotate = np.dot(rotateMat, np.array([[pt2[0]], [pt2[1]], [1]]))# pt3_rotate = np.dot(rotateMat, np.array([[pt3[0]], [pt3[1]], [1]]))# pt4_rotate = np.dot(rotateMat, np.array([[pt4[0]], [pt4[1]], [1]]))# print('==pt1_rotate:', pt1_rotate)# print('==pt2_rotate:', pt2_rotate)# print('==pt3_rotate',  pt3_rotate)# print('==pt4_rotate:', pt4_rotate)[[pt1[0]], [pt1[1]]] = np.dot(rotateMat, np.array([[pt1[0]], [pt1[1]], [1]]))[[pt2[0]], [pt2[1]]] = np.dot(rotateMat, np.array([[pt2[0]], [pt2[1]], [1]]))[[pt3[0]], [pt3[1]]] = np.dot(rotateMat, np.array([[pt3[0]], [pt3[1]], [1]]))[[pt4[0]], [pt4[1]]] = np.dot(rotateMat, np.array([[pt4[0]], [pt4[1]], [1]]))print('==旋转后pt1,pt2,pt3,pt4:', pt1, pt2, pt3, pt4)imgclip = imgRotation[int(pt1[1]):int(pt3[1]), int(pt1[0]):int(pt3[0])]cv2.imwrite(clipImagePath, imgclip)  # 裁减得到的旋转矩形框cv2.imwrite(rotateImagePath, imgRotation)return imgRotation#校正逆时针的四个点 从左上角开始
def cal_stand_points(points):rect = np.zeros((4, 2))s = np.sum(points, axis=1)rect[0] = points[np.argmin(s)]rect[2] = points[np.argmax(s)]# the top-right point will have the smallest difference,# whereas the bottom-left will have the largest differenced = np.diff(points, axis=1)rect[3] = points[np.argmin(d)]rect[1] = points[np.argmax(d)]return rect
def main():points = np.array([[137, 32],[408, 250],[319, 365],[46, 137]])points = cal_stand_points(points)print('===points:', points)img = cv2.imread('./D8_1_LowAngleLight111.jpg')rotate(img, points, rotateImagePath='./out.jpg', clipImagePath='./out_clip.jpg')if __name__ == "__main__":main()

                      原图

              

                   旋转后原图                                                                               裁剪图

方式2:直接做透视变换

import cv2
import numpy as npdef main():img = cv2.imread("./1.jpg")# points for test.jpgcnt = np.array([[408, 250],[137, 32],[319, 365],[46, 137]])rect = cv2.minAreaRect(cnt)print("rect: {}".format(rect))# the order of the box points: bottom left, top left, top right,# bottom rightbox = cv2.boxPoints(rect)box = np.int0(box)print("bounding box: {}".format(box))# get width and height of the detected rectangleshort_side = int(rect[1][0])long_side = int(rect[1][1])src_pts = box.astype("float32")# coordinate of the points in box points after the rectangle has been# straighteneddst_pts = np.array([[long_side-1, short_side-1],[0, short_side - 1],[0, 0],[long_side-1, 0],], dtype="float32")print(src_pts, dst_pts)# the perspective transformation matrixM = cv2.getPerspectiveTransform(src_pts, dst_pts)# directly warp the rotated rectangle to get the straightened rectanglewarped = cv2.warpPerspective(img, M, (long_side, short_side))# return warpedcv2.imwrite("crop_img.jpg", warped)# cv2.waitKey(0)if __name__ == "__main__":main()

十六.获取向外扩充的polygon

from shapely.geometry import Polygon
import pyclipper
import numpy as np#获取每条边向外扩充后的polygon
def unclip(box, unclip_ratio=1.5):poly = Polygon(box)#每条边向外扩充的长度 面积                      周长distance = poly.area * unclip_ratio / poly.lengthoffset = pyclipper.PyclipperOffset()offset.AddPath(box, pyclipper.JT_ROUND, pyclipper.ET_CLOSEDPOLYGON)expanded = np.array(offset.Execute(distance))return expandedimg = np.zeros((700, 700, 3))
points = np.array([[597.40393, 147.45522],[681.53076, 136.4222],[682.52625, 144.01295],[598.3994,  155.04597]]).astype(np.int)
expand_points = unclip(points)
print('==expand_points.shape:', expand_points.shape)
print('==expand_points:', expand_points)cv2.polylines(img, [np.array(points).reshape(-1, 1, 2)], True, (255, 255, 255), thickness=1)
cv2.polylines(img, [np.array(expand_points).reshape(-1, 1, 2)], True, (255, 255, 255), thickness=3)cv2.imwrite('./img_rect.jpg', img)

十七.坐标和图片一起旋转90,180

import numpy as np
#得到左上角开始的顺时针四个点
def cal_stand_points(point):s = np.sum(point, axis=1)left_top_index = np.argmin(s)# right_bottom_index = np.argmax(s)rect = np.roll(point, 4-left_top_index, axis=0)return rect.reshape(-1,).tolist()#文字框旋转90度
def rotate_90(box, w):new_box = np.zeros_like(box)new_box[0::2] = box[1::2]new_box[1::2] = w - box[0::2]new_box = np.roll(new_box, 6)return new_box#文字框旋转180度
def rotate_180(box, w, h):new_box = np.zeros_like(box)new_box[0::2] = w - box[0::2]new_box[1::2] = h - box[1::2]new_box = np.roll(new_box, 6)new_box = cal_stand_points(np.array(new_box).reshape(-1, 2))return new_boximg = np.zeros((80,40))
img_h, img_w = img.shapebox = np.array([0, 0, 20, 0, 20, 20, 0, 20])cv2.polylines(img, [np.array(box).reshape(-1, 1, 2)], True, (255, 255, 255), thickness=2)
cv2.imwrite('./img_ori.jpg', img)new_box = rotate_90(box, img_w)
copy_img = np.rot90(img.copy())
print('=new_box:', new_box)
cv2.polylines(copy_img, [np.array(new_box).reshape(-1, 1, 2)], True, (255, 255, 255), thickness=2)
cv2.imwrite('./img_rot90.jpg', copy_img)copy_img2 = np.rot90(np.rot90(img.copy()))
box = np.array([0, 0, 0, 20, 20, 20, 0, 20])
new_box = rotate_180(box, img_w, img_h)
print('=new_box:', new_box)
cv2.polylines(copy_img2, [np.array(new_box).reshape(-1, 1, 2)], True, (255, 255, 255), thickness=2)
cv2.imwrite('./img_rot180.jpg', copy_img2)

                                    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/493453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Verilog HDL语言设计实现过程赋值+译码器

完成课本例题6.11、6.12&#xff0c;进行综合和仿真&#xff08;功能仿真&#xff09;&#xff0c;查看综合和仿真结果&#xff0c;整理入实验报告。 6.11 module shiyan21(in,clk,out1,out2); input clk,in; output out1,out2; reg out1,out2; always (posedge clk) beg…

【工业4.0】深度报告:独家解密工业4.0真正图谋?跟踪软件帝国的十年

来源&#xff1a;知识自动化要理解工业4.0&#xff0c;就避不开对西门子的研究&#xff1b;而要看懂西门子&#xff0c;不要去要看它的硬件&#xff0c;而要去看它的软件。数字化工厂只是水中花&#xff0c;真正的花朵不在你眼前&#xff0c;而在你身头。德国安贝格和成都的数字…

检测系列--RCNN系列

一.RCNN 框架&#xff1a; 1.selective search 2,区域预处理&#xff0c;尺寸缩放到227227 3.利用Alexnet(去掉最后分类层&#xff0c;4096维向量)&#xff0c;做特征提取&#xff0c;一个物体一个SVM分类&#xff0c;(当时认为SVM比softmax分类好)bounding box回归 4.正负样本…

Verilog HDL语言设计实现D触发器+计数器

分别采用结构描述和行为描述方式设计一个基本的D触发器&#xff0c;在此基础上&#xff0c;采用结构描述的方式&#xff0c;用8个D触发器构成一个8位移位寄存器。进行功能仿真&#xff0c;查看结果&#xff0c;把上述内容整理到实验报告。&#xff08;1&#xff09;行为描述:单…

2018年全球十大新兴技术:细胞植入人体、营养人造肉……你想试试吗?

来源&#xff1a;光明日报摘要&#xff1a;在不久的将来&#xff0c;技术革新将如何改变我们的生活&#xff1f;人工智能将大幅提升新药物和新材料的开发速度&#xff1b;新型诊断工具将打造更先进的个性化医疗&#xff1b;如果你生病了&#xff0c;医生将可以在你体内植入活细…

检测系列--YOLO系列

开头语&#xff1a;RCNN系列&#xff0c;需要区域候选框&#xff0c;即便最后是多任务损失函数&#xff0c;但回归和分类各是一块是很明显的&#xff0c;而yolo要把分类问题转换成回归&#xff0c;这样的話就全是回归。 一.yolo v1 1,介绍&#xff0c;此时输入size要一致448*…

Verilog HDL语言实现ROM、RAM+有限状态机

利用MegaWizard实现创建RAM和ROM。&#xff08;1&#xff09;建立1个32单元8bit的RAM&#xff0c;并将0-31填入该RAM&#xff1b;&#xff08;2&#xff09;建立1个32单元8bit的ROM&#xff0c;建立.mif文件填入数据&#xff0c;并读出来显示。 (1)、RAM 功能代码: module sh…

重磅!亚马逊将在2019年全面弃用Oracle数据库

来源&#xff1a;AI 前线摘要&#xff1a;11 月 29 日&#xff0c;AI 前线获悉&#xff0c;亚马逊 AWS 首席执行官 Andy Jassy 在正在美国拉斯维加斯召开的 AWS re&#xff1a;Invent 2018 中表示&#xff1a;到 2019 年底&#xff0c;亚马逊将全面放弃使用 Oracle 数据库&…

数字图像处理实验6图像编码

一、实验目的 &#xff08;1&#xff09;了解图像编码的目的及意义&#xff0c;加深对图像编码的感性认识。 &#xff08;2&#xff09;熟练掌握哈夫曼编码的实现与应用。 &#xff08;3&#xff09;掌握行程长度编码的实现与应用&#xff0c;尤其是BMP和PCX文件的行程长度编…

机器人日行十万步却无需动力源!究竟如何完美的机械结构让你开始怀疑人身...

来源&#xff1a;机器人大讲堂摘要&#xff1a;上图这个机器人可不简单&#xff0c;它是世界纪录的保持者&#xff0c;目前最新的纪录是连续步行27小时&#xff0c;总长72公里&#xff08;相当于十万步还要多&#xff09;。而最最关键的是&#xff0c;它完全凭借自己完美的机械…

数字图像处理实验5图像复原

一、实验目的 &#xff08;1&#xff09;了解图像复原的目的及意义&#xff0c;加深对图像复原理论的认识。 &#xff08;2&#xff09;掌握维纳滤波复原基本原理。 &#xff08;3&#xff09;掌握约束最小二乘方复原方法。 &#xff08;4&#xff09;掌握盲解卷积复原方法…

MVVM模式的一个小例子

使用SilverLight、WPF也有很长时间了&#xff0c;但是知道Binding、Command的基本用法&#xff0c;对于原理性的东西&#xff0c;一直没有深究。如果让我自己建一个MVVM模式的项目&#xff0c;感觉还是无从下手&#xff0c;最近写了一个小例子&#xff0c;贴上代码&#xff0c;…

实现两个点集的欧式距离和cos距离和索引值寻找(含有两种解法,for循环和矩阵操作)

一.计算欧式距离 1&#xff0c;直接for循环 两个点集points1&#xff0c;points2&#xff0c;用dist来存储距离 points1np.array([[1,2],[3,4]]) points2 np.array([[5, 6],[7,8]]) dist np.zeros(shape[points1.shape[0],points2.shape[0]]) for i in range(points1.sha…

数字图像处理实验四图像频域增强

一、实验目的 &#xff08;1&#xff09;了解图像增强的目的及意义&#xff0c;加深对图像增强的感性认识&#xff0c;巩固所学的图像增强的理论知识和相关算法。 &#xff08;2&#xff09;熟练掌握低通、高通、带通、同态滤波器的使用方法&#xff0c;明确不同性质的滤波器…

卡耐基梅隆大学专家谈核心技术市场化:「AI 周边相关机遇最大」

来源&#xff1a;ZDnet、机器之能编译 | 张玺摘要&#xff1a;技术市场化之难在哪&#xff1f;创业家最常犯什么错误&#xff1f;每位立志创业的朋友都应该研究下这篇对卡耐基梅隆 (CMU) 大学专家的采访。CMU 是全美技术转移最成功的机构之一&#xff0c;斥巨资帮助全校师生实现…

数字图像处理实验三图像增强

一、实验目的 &#xff08;1&#xff09;了解图像增强的目的及意义&#xff0c;加深对图像增强的 感性认识&#xff0c;巩固所学的图像增强的理论知识和相 关算法。 &#xff08;2&#xff09;熟练掌握直方图均衡化和直方图规定化的计算过 程。 &#xff08;3&#xff09;熟…

matplotlib与seaborn的一些使用

1.plt.plot画线画点 a np.array([[1, 2], [3, 4]]) print(a[:, 0]) plt.plot(a[:, 0], a[:, 1]) plt.show() plt.plot(a[:, 0], a[:, 1], o,colorred) plt.show()&#xff03;添加风格 plt.plot(x,y,colorred,linewidth1.0,linestyle--) #设置x轴范围 plt.xlim((-1,2)) # …

无人驾驶汽车想要“普渡众生”,还要经历15个磨难

来源&#xff1a;Forbes 、网易智能摘要&#xff1a;无人驾驶汽车的未来与电动平衡车的历史有什么关系吗&#xff1f;电动平衡车也曾被预言将彻底改变交通。史蒂夫•乔布斯曾经说&#xff0c;城市将围绕这一设备重新设计&#xff1b;约翰•杜尔说&#xff0c;它将比互联网更大…

SQL的各种使用方法

一、Select语句例子 使用子查询查询employees表中&#xff0c;属于某一部门员工的姓名、职位、工薪、部门编号的信息 提示&#xff1a; 1)、需要关联employees表、departments表 2)、已知的信息为部门名称&#xff0c;部门名称由用户自己给出 按照要求写出SQL语句。 答案及…

正常矩形计算IOU与与NMS,多边形计算IOU

一&#xff0e;计算IOU def intersect(box_a, box_b):max_xy np.minimum(box_a[:, 2:], box_b[2:])min_xy np.maximum(box_a[:, :2], box_b[:2])inter np.clip((max_xy - min_xy), a_min0, a_maxnp.inf)return inter[:, 0] * inter[:, 1]def jaccard_numpy(box_a, box_b):&…