日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv基础知识及其一些例子

發布時間:2024/7/23 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)

? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ???

總結

以上是生活随笔為你收集整理的opencv基础知识及其一些例子的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。