【start:2023.07.25】
1. OpenCV-python
1.1. 基础知识
不管是打开一个图像或者是接收矩阵生成一个图像,他们都应为dtype=“uint8”
# 不管是打开一个图像或者是接收矩阵生成一个图像他们都应为dtype=“uint8”
img = cv2.imread(_input, cv2.IMREAD_COLOR) # 使用cv2打开图片
# 注意观察shape,如果有第三维还要看通道数
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY).astype("uint8")
out = out[:,:,0]*255
out = out.astype("uint8")
# print('img.shape[2]',img.shape[2])
# print('out.shape[2]',out.shape[2])
# 创建一个空白图片
line = 255*np.ones((5, 256), np.uint8)
line = cv2.resize(line, (10, 256))
img = cv2.resize(img, (256, 256))
out = cv2.resize(out, (256, 256))
# 图片横向拼接
outs = cv2.hconcat([ img, line, out])
cv2.imwrite('result/result.png',out)
# cv2.imshow('img',img)
# cv2.imshow('out',out)
cv2.imshow('outs',outs)
cv2.waitKey(0)
2. PIL-python
2.1. 基础知识
2.2. PIL和Opencv互转
import cv2
import cv2 as cv
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
def PIL_Opencv(image):
image = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)
return image
def Opencv_PIL(image):
image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
return image
3. FFmpeg插件
【Python】ffmpeg的安装配置和python中使用ffmpy(保姆级图文)
https://blog.csdn.net/u011027547/article/details/122490254
ffmpeg官网
https://ffmpeg.org/download.html
https://www.gyan.dev/ffmpeg/builds/
https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z
3.1. 万能看图
用ffplay打开视频&图片:
E:\lxq\ffmpeg-6.0-full_build\bin\ffplay.exe
3.2. 拷贝视频
import subprocess
## 拷贝前询问是否覆盖
cmd = f"ffmpeg -i {out_mp4} -c copy {out_mp4_.replace('data/out_put', new_folder_path)}"
subprocess.run(cmd.split())
# 拷贝时默认覆盖
cmd = f"ffmpeg -y -i {out_mp4} -c copy {out_mp4_.replace('data/out_put', new_folder_path)}"
subprocess.run(cmd.split())
3.3. 切割视频
# trim video to shorter seconds
# ffmpeg -ss 00:00:05 -to 00:00:10 -y -i data/examples/bella_porch.mp4 -c copy data/out_put/video_mp4.mp4
cmd = f"ffmpeg -ss {min_time} -to {max_time} -y -i {video_input} -c copy {video_mp4}"
subprocess.run(cmd.split())
3.4. 横向拼接视频
cmd = f"ffmpeg -y -i {driving_mp4} -i {out_mp4} -filter_complex hstack=inputs=2 {final_mp4}"
subprocess.run(cmd.split())
3.5. 合并视频
ffmpeg -f concat -safe 0 -i I:\\Su_Lab\\video\\concat.txt -c copy I:\\Su_Lab\\video\\output.mp4
4. 图像格式转换
4.1. img to uint8
也可以把数组转换成图像
转换时要注意:
灰度值的最大值可能256或25536,如果选错uint类型,超出最大值的部分会被“削去”,从而“白”得刺眼
可以直接用PIL库转换
from PIL import Image
Image.fromarray(np.uint8(img))
当img元素的范围是0-1之间时,要乘255,将其转换为0-255
Image.fromarray(np.uint8(255*img))
也可以用下述代码转换
'''
img_to_uint8
trans img's formats(including unit16, float64) to uint8, so the new img can best match opencv plugin.
'''
def get_max(img):
maxx = max(map(max, img))
print('maxx=',maxx)
return maxx
def print_info(img):
print('img.shape:',img.shape)
print('img.dtype',img.dtype)
get_max(img)
def img_to_uint8(raw_img):
# trans to uint8
print('****begin img_to_uint8')
# raw_img = frames[0]
# raw_img=Sobel()
print('raw img.dtype:',raw_img.dtype)
maxx = max(map(max, raw_img))
print('raw maxx:',maxx)
plt.imshow(raw_img)
img = raw_img
if img.dtype=='uint8':
print('raw = uint8')
img_target_8 = img
elif img.dtype=='uint16':
print('raw = uint16')
img = img/256
# 归256化,防止数值太小而丢失数值
maxx = max(map(max, img))
img = img*256/maxx
img_target_8=(img).astype(np.uint8)
elif img.dtype=='float64':
print('raw = float64')
img=(img).astype(np.uint16) #
img_target_8 = img_to_uint8(img)
else:
print('trans format wrong')
img = img_target_8
print('new img.dtype:',img.dtype)
maxx = max(map(max, img))
print('new maxx:',maxx)
plt.imshow(img)
return img
4.2. tif2jpg
'''
tif gen jpg
use gen_jpg function to generate a jpg picture in appointed file,
use gen_all_jpg_in_flie function to generate all jpg in a big file_box.
'''
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
import glob
path = 'D:\\JoeOffice\\jupyter_notebook\\computer_vision\\small_object_track\\H2b_GFP_cell_track\\Fluo-N2DL-HeLa\\Fluo-N2DL-HeLa'
def gen_jpg(path):
# path = r'D:\JoeOffice\jupyter_notebook\computer_vision\small_object_track\H2b_GFP_cell_track\Fluo-N2DL-HeLa\Fluo-N2DL-HeLa\01\t000.tif'
jpg_name = path.split('\\')[-1].replace('.tif','.jpg')
# 加载彩色灰度图像
img = cv.imdecode(np.fromfile(path, dtype=np.uint8), -1)
#图像编码格式转换
img=(img/256).astype(np.uint8)
print(img.dtype)
print(img)
# 二值化
imgray = img
ret, thresh = cv.threshold(imgray, 130, 255, cv.THRESH_BINARY)
plt.imshow(thresh, cmap = None, interpolation = 'bicubic')
# plt.show()
# 转换成RGB图像
img_jpg = cv.cvtColor(thresh, cv.COLOR_GRAY2RGB);
plt.imshow(img_jpg, cmap = None, interpolation = 'bicubic')
plt.axis('off') # 去坐标轴
plt.xticks([]) # 去 x 轴刻度
plt.yticks([]) # 去 y 轴刻度
save_path = 'D:\JoeOffice\jupyter_notebook\computer_vision\small_object_track\H2b_GFP_cell_track\my_fluo_img\\'+jpg_name
# # 仅保存
# plt.savefig(save_path, bbox_inches='tight')
# 仅展示
plt.show()
def gen_all_jpg_in_flie(image_path):
print('open')
print(image_path + '\*.tif')
# print(glob.glob(image_path + '\*.tif'))
image_name_box = glob.glob(image_path + '\*.tif')
for index, jpg_file in enumerate(image_name_box):
print(index, jpg_file)
if index <2:
gen_jpg(jpg_file)
# gen_jpg(jpg_file)
gen_all_jpg_in_flie(path + r'\01')
4.3. czi2tif
import czifile
path='xxx.czi'
# trans czi to to tif img
czifile.czi2tif(path)
4.4. 单通道图片生成三通道图片
'''
单通道->三通道
'''
import os
import cv2
import numpy as np
import PIL.Image as Image
import os
#os.environ['CUDA_VISIBLE_DEVICES'] = '2'
img_path='D:\JoeOffice\jupyter_notebook\computer_vision\segmentation\pytorch-UNet-master\labelme-main\examples\semantic_segmentation\img_4\\'
save_img_path='D:\JoeOffice\jupyter_notebook\computer_vision\segmentation\pytorch-UNet-master\labelme-main\examples\semantic_segmentation\img_3\\'
for img_name in os.listdir(img_path):
image=Image.open(img_path+img_name)
if len(image.split())==1: #查看通道数
print(len(image.split()))
print(img_path+img_name)
img = cv2.imread(img_path + img_name)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = np.zeros_like(img)
img2[:, :, 0] = gray
img2[:, :, 1] = gray
img2[:, :, 2] = gray
img_name = img_name.replace('png', 'jpg')
cv2.imwrite(save_img_path + img_name, img2)
image = Image.open(save_img_path + img_name)
print(len(image.split()))
elif len(image.split())==4: #查看通道数
print(len(image.split()))
print(img_path+img_name)
img = cv2.imread(img_path+img_name)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = np.zeros_like(img)
img2[:,:,0] = gray
img2[:,:,1] = gray
img2[:,:,2] = gray
img_name = img_name.replace('png','jpg')
cv2.imwrite(save_img_path+img_name, img2)
image=Image.open(save_img_path+img_name)
print(len(image.split()))
else:
print(len(image.split()))
print('road != 1,4')
image.save(save_img_path+img_name)
'''
单通道->三通道
'''
#img_src = np.expand_dims(img_src, axis=2)
#img_src = np.concatenate((img_src, img_src, img_src), axis=-1)
5. 视频格式转换
5.1. czi
5.1.1. czi2gif
import numpy as np
import imageio
from czifile import CziFile
'''
czi转gif
https://pypi.org/project/czifile/#files
'''
def czi_to_gif(czi_path, gif_path, fps=10):
with CziFile(czi_path) as czi:
# Read the CZI file
image_array = czi.asarray()
# print(image_array)
print(image_array.shape)
# Convert CZI image array to GIF image sequence
image_sequence = []
for t in range(image_array.shape[0]):
# Select a single time point
frame = image_array[t][0,0,:,:,0]
# Normalize pixel values to 0-255
frame = img_to_uint8(frame)
# Append to image sequence
image_sequence.append(frame)
# Save as GIF file
imageio.mimsave(gif_path, image_sequence, fps=fps)
import glob
import os
in_folder = os.path.join(r'D:\JoeOffice\jupyter_notebook\computer_vision\instance_segmentation\MultiStar-main\datagen\data\PEG\czi','*.czi')
czi_paths = glob.glob(in_folder)
print(czi_paths)
for czi_path in czi_paths:
gif_path = czi_path.replace('czi', 'gif')
czi_to_gif(czi_path, gif_path, fps=10)
5.1.2. czi2tif
# czi2tif
import czifile
path=r'E:\dataset\PEG\Image 7 Block 2_SIM.czi'
# trans czi to to tif img
czifile.czi2tif(path)
5.2. tif
5.2.1. tif帧数+尺寸查询
# tif帧数+尺寸查询
import tifffile
# 打开TIFF视频文件
video_path = r'E:\dataset\PEG\block2sim.tif'
video = tifffile.TiffFile(video_path)
# 获取视频的帧数
num_frames = len(video.pages)
# 获取视频的形状(shape)即每帧数据的维度
shape_of_frame = video.pages[0].shape
# 输出帧数和形状
print(f"TIFF视频帧数:{num_frames} 帧")
print(f"每帧数据的形状(shape):{shape_of_frame}")
# 关闭文件
video.close()
5.2.2. 查询tif文件的结构
在某些情况下,一个TIFF文件可能同时包含"Pages"(页)和"Series"(系列)。这是由于TIFF格式的灵活性和多功能性。
-
Pages(页):
"Pages"是TIFF文件的基本组成单位,每个页可以包含一个独立的图像或数据块。这种情况下,TIFF文件就类似于一个多页文档,每个页可以看作是其中的一页。这种用法常见于单页扫描的TIFF文档或者将多个单页图像保存在一个文件中的情况。 -
Series(系列):
"Series"是用于组织多维数据或时间序列数据的一种机制。每个系列可以包含多个页,每个页代表一个相关的数据时间步或切片。这种用法通常用于科学和地理空间数据,如卫星图像时间序列或者多维医学图像数据。
为了更好地组织和表示多维或时间相关的数据,有时会在一个TIFF文件中同时使用"Pages"和"Series"。例如,假设一个实验生成了100个时间步的数据,并将每个时间步的数据保存在单独的页(Pages)中,那么整个实验就可以被组织成一个包含100个系列(Series)的TIFF文件,其中每个系列代表一个时间步。这样的组织方式既能保持TIFF文件的结构完整性,又可以方便地访问和处理多个时间步的数据。
需要注意的是,并非所有的TIFF文件都同时使用"Pages"和"Series"。TIFF格式的使用可以根据数据类型、生成方式和使用场景而异。在处理TIFF文件时,最好先了解其具体结构和组织方式,以便正确地读取和处理其中的数据。
import tifffile as tf
def print_tiff_info(tiff_file_path):
with tf.TiffFile(tiff_file_path) as tif:
# Print basic information
print("TIFF File Information:")
print(f"tif: {tif}")
print(f"Filename: {tif.filename}")
print(f"Number of pages: {len(tif.pages)}")
print(f"tif: {tif.series}")
if __name__ == "__main__":
# tiff_file_path = r"D:\JoeOffice\jupyter_notebook\computer_vision\SR\3D-RCAN-master\data\rcan\test\4-after_4_PEG-FRAP.tif" # 替换为你的TIFF文件路径
tiff_file_path = r"D:\JoeOffice\jupyter_notebook\computer_vision\SR\3D-RCAN-master\data\rcan\input\5-8%_PEG-normal_media.tif" # 替换为你的TIFF文件路径
print_tiff_info(tiff_file_path)
5.2.3. tif视频时长+尺寸裁剪
# tif视频时长+尺寸裁剪
import tifffile
# 打开TIFF视频文件
video_path = r'E:\dataset\PEG\block2sim.tif'
video = tifffile.TiffFile(video_path)
# 获取视频的帧数
num_frames = len(video.pages)
# 确保要提取的帧范围在有效范围内
start_frame = 10
end_frame = 30
if start_frame < 1:
start_frame = 1
if end_frame > num_frames:
end_frame = num_frames
# 逐帧提取并保存
output_path = r'E:\dataset\PEG\block2sim_crop.tif'
cropped_frames = []
for frame_number in range(start_frame - 1, end_frame): # 注意索引从0开始
frame_data = video.pages[frame_number].asarray()
if frame_number == start_frame-1:
print(frame_data.shape)
w = frame_data.shape[0]
h = frame_data.shape[1]
print(w,h)
a = 0.3
b = 1-a
x1 = int(a*w)
x2 = int(b*w)
y1 = int(a*h)
y2 = int(b*h)
cropped_frame = frame_data[x1:x2, y1:y2] # 裁剪为左上角的256x256尺寸
cropped_frames.append(cropped_frame)
# 将裁剪后的帧保存为新的TIFF文件
tifffile.imwrite(output_path, cropped_frames)
# 关闭文件
video.close()
5.2.4. tif与gif互转
import imageio
import os
import numpy as np
'''
gif和tif互转
'''
def gif_to_tiff_video(gif_path, tiff_video_output_path, target_format):
try:
gif_images = imageio.mimread(gif_path)
except FileNotFoundError:
print("找不到 GIF 文件:", gif_path)
return
# 逐帧保存为图像序列
for i, gif_image in enumerate(gif_images):
tiff_frame_output_path = f"{tiff_video_output_path}_{i}.tif"
imageio.imwrite(tiff_frame_output_path, gif_image, format=target_format)
# 将图像序列合并为视频
if target_format == 'tif':
with imageio.get_writer(tiff_video_output_path, format=target_format) as writer:
whole_tiff_file = [0 for x in range(len(gif_images))]
for i in range(len(gif_images)):
tiff_frame_path = f"{tiff_video_output_path}_{i}.tif"
tiff_frame_image = imageio.imread(tiff_frame_path)
# 注意,这里要把tiff_frame_image整理好后,一次性传入writer中,这样返回的tif文件的格式就会是多个pages和一个series;如果分多次传入,则会有多个series,不符合tif文件的常态
whole_tiff_file[i] = tiff_frame_image[:,:,0]
writer.append_data(whole_tiff_file)
elif target_format == 'gif':
with imageio.get_writer(tiff_video_output_path, format=target_format) as writer:
for i in range(len(gif_images)):
tiff_frame_path = f"{tiff_video_output_path}_{i}.tif"
tiff_frame_image = imageio.imread(tiff_frame_path)
# writer.append_data(np.expand_dims(tiff_frame_image[:,:,0], axis=0))
# writer.append_data(tiff_frame_image[:,:,0])
writer.append_data(tiff_frame_image)
# 删除临时的TIFF图像序列文件
for i in range(len(gif_images)):
tiff_frame_path = f"{tiff_video_output_path}_{i}.tif"
if os.path.exists(tiff_frame_path):
os.remove(tiff_frame_path)
print("TIFF视频转换完成!")
# 使用示例
if __name__ == "__main__":
# target_format为output的格式,可取'gif','tif'
target_format='tif'
gif_file_path = r"D:\JoeOffice\jupyter_notebook\computer_vision\SR\3D-RCAN-master\data\rcan\test\4-after_4_PEG-FRAP.gif"
tiff_video_output_path = r"D:\JoeOffice\jupyter_notebook\computer_vision\SR\3D-RCAN-master\data\rcan\test\4-after_4_PEG-FRAP." + target_format
gif_to_tiff_video(gif_file_path, tiff_video_output_path, target_format=target_format)
6. 图像生成视频
6.1. 生成标准编号
生成长度一致的编号,不足长度的地方用“0”补齐
path_prefix = 'D:\JoeOffice\jupyter_notebook\computer_vision\particle_track\PEG\PEG_small_cut\PEG_small_cut'
def saveImg_with_regularIndex(path_prefix):
len_index_name = 4
if len(str(i))<=len_index_name:
len_index_offset = (len_index_name-len(str(i)))*'0'+str(i)
save_path = path_prefix + len_index_offset
plt.savefig(save_path, bbox_inches='tight',pad_inches = 0 )
plt.show()
else:
save_path = path_prefix + str(i)
plt.savefig(save_path, bbox_inches='tight',pad_inches = 0 )
plt.show()
saveImg_with_regularIndex(path_prefix)
6.2. img2gif
把一个文件夹里的所有图片按一定顺序制作成gif
import imageio, os, sys
'''
img gen gif
'''
def png_gif(path):
# 需要将文件规范命名
png_lst = os.listdir(path)
frames = []
for i in png_lst:
frames.append(imageio.imread(path + i))
imageio.mimsave("new_gif.gif", frames, 'GIF', duration=0.2)
def main():
# 注意路径后要加两条斜杠
path = r'D:\JoeOffice\jupyter_notebook\math_science\deeplearning_maozhiping\Possion_2D_demo\Possion_2D_demo_test\Output_iter_pic\\'
png_gif(path)
if __name__=="__main__":
main()
注意,上面的函数有一个bug,os.listdir(path)会把60插入到600之前
解决方法:将原来文件规范命名,如:当最大值是三位数时,10改成010,20改成020
【ref】os.listdir(path)避坑指南
6.3. cut img
截取图片的一小块,并制作成gif
'''
cut img and gen gif
'''
import matplotlib as mpl
import matplotlib.pyplot as plt
import imageio, os, sys
def png_gif(path):
# 需要将文件规范命名
png_lst = os.listdir(path)
frames = []
i = 0
for png_name in png_lst:
print(png_name)
pic = imageio.imread(path + png_name)
pic_cut = pic[30:180,170:320,:]
blank = pic*0
blank[30:180,170:320,:] = pic_cut
cv2.imshow('pic', pic)
cv2.imshow('blank', blank)
cv2.imshow('pic_cut', pic_cut)
# cv2.waitKey(0)
plt.axis('off')
plt.imshow(blank)
# print(pic.shape)
len_step_name = 3
if len(str(i))<=len_step_name:
len_offset = (len_step_name-len(str(i)))*'0'+str(i)
save_path_img_fliter = r'D:\JoeOffice\jupyter_notebook\computer_vision\particle_track\PEG\PEG_fliter_small_cut_img\\'+'PEG_fliter_small_cut_' + len_offset
plt.savefig(save_path_img_fliter)
else:
save_path_img_fliter = r'D:\JoeOffice\jupyter_notebook\computer_vision\particle_track\PEG\PEG_fliter_small_cut_img\\'+'PEG_fliter_small_cut_' + str(i)
plt.savefig(save_path_img_fliter)
plt.savefig(save_path_img_fliter, bbox_inches='tight',pad_inches = 0)
i=i+1
def main():
# 注意路径后要加两条斜杠
path = 'D:\JoeOffice\jupyter_notebook\computer_vision\particle_track\PEG\PEG_fliter_img_less\\'
png_gif(path)
if __name__=="__main__":
main()