哪個網(wǎng)站做任務(wù)能賺錢我要看今日頭條
一、計算機眼中的圖像
1.圖像操作
構(gòu)成像素點的數(shù)字在0~255之間
RGB叫做圖像的顏色通道
?h=500,w=500
?
?2.灰度圖像
3. 彩色圖像
?4.圖像的讀取
?5.視頻的讀取
cv2.VideoCapture()--在OpenCV中,可以使用VideoCapture來讀取視頻文件,或是攝像頭數(shù)據(jù)。
cv2.VideoCapture.isOpened()--判斷文件打開是否成功,可以使用cv2.VideoCapture.isOpened()這個函數(shù)。
cv2.VideoCapture.read()--cv2.VideoCapture.read()提供了一個最簡單的視頻幀處理方式,集合了抓起Grab(),解碼retrieve()兩個功能,返回解碼之后的數(shù)據(jù)。需要特別注意的是,如果獲取到空幀,抓取失敗或是文件結(jié)束,返回值會是一個空指針
示例:
VideoCapture也是支持讀取攝像頭的,提供rtsp碼流即碼流地址,
?二
1.截取部分圖像數(shù)據(jù)
import os
import cv2 # 遍歷指定目錄,顯示目錄下的所有文件名
def CropImage4File(filepath,destpath):pathDir = os.listdir(filepath) # 列出文件路徑中的所有路徑或文件for allDir in pathDir:child = os.path.join(filepath, allDir)dest = os.path.join(destpath,allDir)if os.path.isfile(child):image = cv2.imread(child) sp = image.shape #獲取圖像形狀:返回【行數(shù)值,列數(shù)值】列表sz1 = sp[0] #圖像的高度(行 范圍)sz2 = sp[1] #圖像的寬度(列 范圍)#sz3 = sp[2] #像素值由【RGB】三原色組成#你想對文件的操作a=int(sz1/2-64) # x startb=int(sz1/2+64) # x endc=int(sz2/2-64) # y startd=int(sz2/2+64) # y endcropImg = image[a:b,c:d] #裁剪圖像cv2.imwrite(dest,cropImg) #寫入圖像路徑if __name__ == '__main__':filepath ='F:\\\maomi' #源圖像destpath='F:\\maomi_resize' # resized images saved hereCropImage4File(filepath,destpath)
2. 截取部分圖像數(shù)據(jù)-批量處理
"""
處理數(shù)據(jù)集 和 標簽數(shù)據(jù)集的代碼:(主要是對原始數(shù)據(jù)集裁剪)處理方式:分別處理注意修改 輸入 輸出目錄 和 生成的文件名output_dir = "./label_temp"input_dir = "./label"
"""
import cv2
import os
import sys
import timedef get_img(input_dir):img_paths = []for (path,dirname,filenames) in os.walk(input_dir):for filename in filenames:img_paths.append(path+'/'+filename)print("img_paths:",img_paths)return img_pathsdef cut_img(img_paths,output_dir):scale = len(img_paths)for i,img_path in enumerate(img_paths):a = "#"* int(i/1000)b = "."*(int(scale/1000)-int(i/1000))c = (i/scale)*100time.sleep(0.2)print('正在處理圖像: %s' % img_path.split('/')[-1])img = cv2.imread(img_path)weight = img.shape[1]if weight>1600: # 正常發(fā)票cropImg = img[50:200, 700:1500] # 裁剪【y1,y2:x1,x2】#cropImg = cv2.resize(cropImg, None, fx=0.5, fy=0.5,#interpolation=cv2.INTER_CUBIC) #縮小圖像cv2.imwrite(output_dir + '/' + img_path.split('/')[-1], cropImg)else: # 卷簾發(fā)票cropImg_01 = img[30:150, 50:600]cv2.imwrite(output_dir + '/'+img_path.split('/')[-1], cropImg_01)print('{:^3.3f}%[{}>>{}]'.format(c,a,b))if __name__ == '__main__':output_dir = "../img_cut" # 保存截取的圖像目錄input_dir = "../img" # 讀取圖片目錄表img_paths = get_img(input_dir)print('圖片獲取完成 。。。!')cut_img(img_paths,output_dir)
3.?多進程(加快處理)
#coding: utf-8
"""
采用多進程加快處理。添加了在讀取圖片時捕獲異常,OpenCV對大分辨率或者tif格式圖片支持不好
處理數(shù)據(jù)集 和 標簽數(shù)據(jù)集的代碼:(主要是對原始數(shù)據(jù)集裁剪)處理方式:分別處理注意修改 輸入 輸出目錄 和 生成的文件名output_dir = "./label_temp"input_dir = "./label"
"""
import multiprocessing
import cv2
import os
import timedef get_img(input_dir):img_paths = []for (path,dirname,filenames) in os.walk(input_dir):for filename in filenames:img_paths.append(path+'/'+filename)print("img_paths:",img_paths)return img_pathsdef cut_img(img_paths,output_dir):imread_failed = []try:img = cv2.imread(img_paths)height, weight = img.shape[:2]if (1.0 * height / weight) < 1.3: # 正常發(fā)票cropImg = img[50:200, 700:1500] # 裁剪【y1,y2:x1,x2】cv2.imwrite(output_dir + '/' + img_paths.split('/')[-1], cropImg)else: # 卷簾發(fā)票cropImg_01 = img[30:150, 50:600]cv2.imwrite(output_dir + '/' + img_paths.split('/')[-1], cropImg_01)except:imread_failed.append(img_paths)return imread_faileddef main(input_dir,output_dir):img_paths = get_img(input_dir)scale = len(img_paths)results = []pool = multiprocessing.Pool(processes = 4)for i,img_path in enumerate(img_paths):a = "#"* int(i/10)b = "."*(int(scale/10)-int(i/10))c = (i/scale)*100results.append(pool.apply_async(cut_img, (img_path,output_dir )))print('{:^3.3f}%[{}>>{}]'.format(c, a, b)) # 進度條(可用tqdm)pool.close() # 調(diào)用join之前,先調(diào)用close函數(shù),否則會出錯。pool.join() # join函數(shù)等待所有子進程結(jié)束for result in results:print('image read failed!:', result.get())print ("All done.")if __name__ == "__main__":input_dir = "D:/image_person" # 讀取圖片目錄表output_dir = "D:/image_person_02" # 保存截取的圖像目錄main(input_dir, output_dir)
?4.顏色通道提取
在OpenCV中,cv2.split() 函數(shù)用于將多通道數(shù)組(如彩色圖像)拆分為多個單通道數(shù)組。彩色圖像通常由多個顏色通道組成,例如BGR(藍綠紅)彩色空間中的三個通道。cv2.split() 函數(shù)將這些通道拆分為獨立的數(shù)組,每個數(shù)組只包含一個通道的信息。
以下是使用 cv2.split() 的示例代碼:
import cv2# 讀取一張彩色圖片
image = cv2.imread('path_to_your_color_image.jpg')# 使用 cv2.split() 拆分通道
b, g, r = cv2.split(image)# 此時,b, g, r 分別包含藍色、綠色和紅色通道的圖像數(shù)據(jù)# 如果你想查看每個通道的圖像,可以這樣做:
cv2.imshow('Blue Channel', b)
cv2.imshow('Green Channel', g)
cv2.imshow('Red Channel', r)# 等待按鍵,然后關(guān)閉窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
?5.合并顏色通道
cv2.merge() 是 OpenCV 中用來合并多個單通道圖像為一個多通道圖像的函數(shù)。它的工作原理與 cv2.split() 相反。如果你有幾個單通道圖像(例如,從 cv2.split() 得到的),并且你想將它們合并成一個多通道圖像(例如,一個彩色圖像),那么你可以使用 cv2.merge()。
以下是 cv2.merge() 的基本用法:
import cv2# 假設(shè)你有三個單通道圖像:b, g, r
# 這些通常是通過 cv2.split() 從一個彩色圖像中得到的
b = ... # 藍色通道圖像
g = ... # 綠色通道圖像
r = ... # 紅色通道圖像# 使用 cv2.merge() 將它們合并為一個彩色圖像
bgr_image = cv2.merge([b, g, r])# 現(xiàn)在 bgr_image 是一個包含 b, g, r 三個通道的彩色圖像
在 cv2.merge() 函數(shù)中,你需要傳遞一個列表作為參數(shù),該列表包含你想要合并的所有單通道圖像。合并的順序很重要,因為它決定了輸出圖像中通道的順序。在上述示例中,我們按照 BGR(藍綠紅)的順序合并了通道,這是 OpenCV 中彩色圖像的標準通道順序。
如果你想合并的通道順序與 BGR 不同,例如 RGB(紅綠藍)順序,你需要相應(yīng)地調(diào)整通道的順序:
rgb_image = cv2.merge([r, g, b])
請注意,cv2.merge() 要求所有輸入圖像都具有相同的大小和類型。如果它們的大小或類型不匹配,函數(shù)將拋出一個錯誤。
在處理圖像時,理解通道的順序和類型非常重要,因為不同的圖像處理庫和函數(shù)可能會使用不同的通道順序和數(shù)據(jù)類型。OpenCV 使用 BGR 順序,而一些其他庫(如 PIL/Pillow)則使用 RGB 順序。因此,在將圖像從一個庫傳遞到另一個庫時,可能需要進行通道順序的轉(zhuǎn)換。
6.邊界填充
cv2.copyMakeBorder() 是 OpenCV 庫中的一個函數(shù),用于在圖像周圍創(chuàng)建邊框。cv2.copyMakeBorder(src,top,bottom,left,right,borderType,value)
下面是該函數(shù)的參數(shù)及其解釋:
src:要處理的輸入圖像。
top:在源圖像的頂部添加的像素數(shù)目。
bottom:在源圖像的底部添加的像素數(shù)目。
left:在源圖像的左側(cè)添加的像素數(shù)目。
right:在源圖像的右側(cè)添加的像素數(shù)目。
borderType:邊框類型,可以是以下之一:
cv2.BORDER_CONSTANT:添加一個常量值的邊框。此時需要提供一個value參數(shù),用于指定常量值。
cv2.BORDER_REPLICATE:復制源圖像的邊界像素。
cv2.BORDER_REFLECT:對源圖像的邊界進行反射,比如:fedcba|abcdefgh|hgfedcb
cv2.BORDER_REFLECT_101:對源圖像的邊界進行反射,但略微不同,比如:gfedcb|abcdefgh|gfedcba
cv2.BORDER_WRAP:對源圖像的邊界進行包裝,比如:cdefgh|abcdefgh|abcdefg
value(可選):當borderType為cv2.BORDER_CONSTANT時,指定的常量值。
該函數(shù)返回一個新的圖像,其大小為原始圖像加上指定邊框大小,并且根據(jù)指定的邊框類型進行填充。
?示例代碼:
image = cv2.imread('./img/dog21.png')
image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
# 定義填充參數(shù)
top_border = 10
bottom_border = 10
left_border = 10
right_border = 10# 使用常數(shù)填充,填充值為0
bordered_image_constant = cv2.copyMakeBorder(image, top_border, bottom_border, left_border, right_border, cv2.BORDER_CONSTANT, value=0)# 使用邊界復制
bordered_image_replicate = cv2.copyMakeBorder(image, top_border, bottom_border, left_border, right_border, cv2.BORDER_REPLICATE)# 使用邊界反射
bordered_image_reflect = cv2.copyMakeBorder(image, top_border, bottom_border, left_border, right_border, cv2.BORDER_REFLECT)# 使用邊界反射101
bordered_image_reflect_101 = cv2.copyMakeBorder(image, top_border, bottom_border, left_border, right_border, cv2.BORDER_REFLECT_101)# 使用邊界包裹
bordered_image_wrap = cv2.copyMakeBorder(image, top_border, bottom_border, left_border, right_border, cv2.BORDER_WRAP)# 創(chuàng)建子圖
fig, ((ax1, ax2, ax3),(ax4, ax5,ax6)) = plt.subplots(2, 3, figsize=(20, 10), sharex=True, sharey=True)# 顯示圖像
ax1.imshow(image.copy())
ax1.set_title('original')
ax2.imshow(bordered_image_constant)
ax2.set_title('constant')
ax3.imshow(bordered_image_replicate, cmap='gray')
ax3.set_title('replicate')
ax4.imshow(bordered_image_reflect, cmap='gray')
ax4.set_title('reflect')
ax5.imshow(bordered_image_reflect_101, cmap='gray')
ax5.set_title('reflect_101')
ax6.imshow(bordered_image_wrap, cmap='gray')
ax6.set_title('wrap')
plt.show()
Python OpenCV庫中的邊界填充通常用于圖像處理,比如二值化后的邊緣增強、腐蝕膨脹操作后的填補空洞等。邊界填充函數(shù)cv2.floodFill()是一個常用工具。這個函數(shù)會在指定起點周圍填充特定顏色,直到遇到另一個更大區(qū)域或者達到邊界條件。
以下是一個基本的使用示例:
import cv2
import numpy as np# 假設(shè)img是你的輸入圖像,前景像素是白色,背景是黑色
img = ... # 你的圖像數(shù)組# 定義起始點和填充的顏色
seed_point = (x, y) # 起始填充點的坐標
new_color = (255, 255, 255) # 填充的新顏色,這里是白色# 應(yīng)用 floodFill
mask = np.zeros(img.shape[:2], dtype=np.uint8)
cv2.floodFill(img, mask, seed_point, new_color)# 顯示結(jié)果
cv2.imshow("Filled Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
?7.數(shù)值計算
?
?cv2.add()函數(shù)中,如果像素點相加之和超過255則最大只能為255,不超過則不變
8.圖像融合
兩個圖片shape值如果不一樣不能做數(shù)值計算
resize函數(shù)
?
?
?1.圖像尺寸調(diào)整
cv2.resize(img,(w,h)):調(diào)整圖像img尺寸到w*h;
cv2.resize(img,(0,0),fx=3,fy=1):將w、h設(shè)置為0,fx為x向相對原圖的比例,fy為y向相對于原圖的比例,fx與fy大于1時圖像為放大,小于1時為縮小。
2.圖像融合
imgf=cv2.addWeighted(img1,α,img2,β,b)
img1與img2為需要融合的圖像
α和β為兩張圖的融合系數(shù)
b為圖像偏置量
計算方式:imgf=α×img1+β×img2+b
注意:兩張可融合的圖片必須尺寸一致,如不一致,需通過resize操作調(diào)整為一致方可融合
示例代碼
import cv2
import os
os.chdir('e://text')
img1=cv2.imread('wanzi.png')
img2=cv2.imread('car.jpg')
def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
print(img1.shape)
print(img2.shape)
img2=cv2.resize(img2,(396,203))
#注意此句,img.shape的數(shù)值時(h,w),而resize需要的輸入是(w,h),兩者是顛倒的
print(img2.shape)
a=cv2.addWeighted(img,1,img2,0.5,0)
#注意:相加后,像素中加和超過255的值會被置為255
cv_show('a',a)