斑马鱼背景建模 & NP.array与PIL.Image格式的图片的互换

参考博客:https://www.jianshu.com/p/58c6ca1b66af

MY:

1. 视频产生图片

#! /usr/bin/env python
import cv2
import os
import glob


def video2imgs(videoPath, savePicturePath):  # imgs_dir是图片所在文件夹路径
    cap = cv2.VideoCapture(videoPath)  # 视频路径
    numFrame = 0  # 用于写出图片的命名
    numFrame = numFrame  # 从1开始,这根据自己需要调整

    while True:
        if cap.grab():  # 如果成功获取图片
            flag, frame = cap.retrieve()
            if not flag:
                print('no flag: flag, frame = cap.retrieve()')
                continue
            else:
                # cv2.imshow('video', frame)
                numFrame += 1  # 用于写出图片的命名
                n = str(numFrame)  # 字符化
                n = n.zfill(8)  # 这样就是八位数, 前面自动补充0
                newPath = savePicturePath + n + ".jpg"  # 输出图片的具体路径 = 输出图片的文件夹 + 图片名字.jpg
                print(n)
                cv2.imencode('.jpg', frame)[1].tofile(newPath)  # 关于这个[1]暂时没有具体研究, 可以查看相关资料
                if numFrame == 100:
                    break

        else:
            print('no cap.grab()')
            break
        if cv2.waitKey(10) == 27:
            break


if __name__ == '__main__':
    video2imgs(
        '/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_fishbox/nk_background_sub/fish_video.avi',
        '/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_fishbox/nk_background_sub/img/')

斑马鱼背景建模 & NP.array与PIL.Image格式的图片的互换_第1张图片
 

2. 100帧混合背景

# -*- coding=utf-8 -*-
# Author: zjc
# Creation Date:19-8-30
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import cv2
import os
import glob

# 读取帧数
img_number = 100

# 各帧的集合
all_img = [np.array(Image.open(
    '/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_fishbox/nk_background_sub/img/' + str(i + 1).zfill(
        8) + '.jpg', 'r'))
    for i in range(img_number)]

# 帧的宽高
h = all_img[0].shape[0]
v = all_img[0].shape[1]
t = all_img[0].shape[2]

# 计算得到背景
back_img = np.zeros((h, v, t))
for single_img in all_img:
    back_img += single_img
back_img /= img_number

img = back_img
print('=>图片:', img)
print('=>形状:', img.shape)
print('=>类型:', type(img))
img = Image.fromarray(np.uint8(img))
img = img.convert('RGB')
img.save('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_fishbox/nk_background_sub/background.jpg')
# 保存背景
# Image.fromarray(back_img).convert('RGB').save(  #
#    '/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_fishbox/nk_background_sub/img//background.jpg')


'''

# 原视频与背景逐帧相减后取绝对值 得到前景
front_img = np.array([i - back_img for i in all_img])
front_img = front_img.__abs__()

# 前景二值化 设定阈值将前景像素值化为0或1
threshold_level = 50
threshold = np.full((h, v), threshold_level)
front_img = np.array([i < threshold for i in front_img], dtype=np.int8)*255

# 在原帧上抠图 得到真实的前景
front_img = np.fmax(np.array(front_img), all_img)

# 保存
for i in range(img_number):
    Image.fromarray(front_img[i]).convert('RGB').save('F:/output/'+str(i+1)+'.jpg')

# 显示
loc_h = 6
loc_v = int(img_number / loc_h)
for i in range(loc_h * loc_v):
    plt.subplot(loc_v, loc_h, i+1)
    plt.imshow(front_img[i], cmap='gray')
plt.show()
'''

 

00000001.jpg为例

斑马鱼背景建模 & NP.array与PIL.Image格式的图片的互换_第2张图片100帧混合斑马鱼背景建模 & NP.array与PIL.Image格式的图片的互换_第3张图片

3 重点解释

https://www.jianshu.com/p/18dabefa6778

1. PIL image转换成array

img = np.asarray(image)

img=np.array(image)
需要注意的是,如果出现read-only错误,并不是转换的错误,一般是你读取的图片的时候,默认选择的是"r","rb"模式有关。

修正的办法: 手动修改图片的读取状态
img.flags.writeable = True # 将数组改为读写模式

或者

im = Image.open("lena.jpg")

# 显示图片
im.show() 

im = im.convert("L") 
data = im.getdata()
data = np.matrix(data)

或者

im = np.array(pil_im)

2. array转换成image

方法1

from PIL import Image
Image.fromarray(np.uint8(img))

注意img如果是uint16的矩阵而不转为uint8的话,Image.fromarray这句会报错  相当关键

File "/usr/local/lib/python2.7/site-packages/PIL/Image.py", line 1884, in fromarray
raise TypeError("Cannot handle this data type")
TypeError: Cannot handle this data type

类似这个问题

PIL weird error after resizing image in skimage

因为:一般在PIL是uint8格式无符号8位整型

斑马鱼背景建模 & NP.array与PIL.Image格式的图片的互换_第4张图片

4 因为1000帧结果不好

我想提取一部分ROI放在另一部分鱼影子上

斑马鱼背景建模 & NP.array与PIL.Image格式的图片的互换_第5张图片

 

 

 

参考博客的:

import matplotlib.pyplot as plt
import numpy as np
from PIL import Image

# 读取帧数
img_number = 48

# 各帧的集合
all_img = [np.array(Image.open('F:/input/'+str(i+1)+'.jpg', 'r')) for i in range(img_number)]

# 帧的宽高
h = all_img[0].shape[0]
v = all_img[0].shape[1]

# 计算得到背景
back_img = np.zeros((h, v))
for single_img in all_img:
    back_img += single_img
back_img /= img_number

# 保存背景
Image.fromarray(back_img).convert('RGB').save('F:/output/background.jpg')

# 原视频与背景逐帧相减后取绝对值 得到前景
front_img = np.array([i - back_img for i in all_img])
front_img = front_img.__abs__()

# 前景二值化 设定阈值将前景像素值化为0或1
threshold_level = 50
threshold = np.full((h, v), threshold_level)
front_img = np.array([i < threshold for i in front_img], dtype=np.int8)*255

# 在原帧上抠图 得到真实的前景
front_img = np.fmax(np.array(front_img), all_img)

# 保存
for i in range(img_number):
    Image.fromarray(front_img[i]).convert('RGB').save('F:/output/'+str(i+1)+'.jpg')

# 显示
loc_h = 6
loc_v = int(img_number / loc_h)
for i in range(loc_h * loc_v):
    plt.subplot(loc_v, loc_h, i+1)
    plt.imshow(front_img[i], cmap='gray')
plt.show()

 

%将视频转换为图片
clear
clc

file_name = 'F:\input.avi';       %视频所在文件夹
obj = VideoReader(file_name);     %读取视频文件

numFrames = obj.NumberOfFrames;   %视频总的帧数 
for k = 1: numFrames
    frame = read(obj,k);
    %imshow(frame);                
    gray_frame = rgb2gray(frame); %若每一帧为彩色图片,转换为灰度图
    imshow(frame);                %显示每一帧图片
    %保存每一帧图片
    imwrite(gray_frame,strcat('F:\input\',num2str(k),'.jpg'),'jpg');
end

你可能感兴趣的:(Zebrafish)