使用直方图法把视频的背景变成白色 python

直方图法确定阈值,实现图像白化,参考链接

https://blog.csdn.net/qq_43620967/article/details/121995903

#将素材中的人嵌入风景中,方法是
#视频的背景颜色(纯白色),关键在于确定阈值,第一次使用的方法是手动确定阈值,
#贴近人的边缘有噪声点  low_value = np.array([-1, 2, 110])  high_value = np.array([255, 50, 255])
#在老师的指导下,使用了一种更好的方法,直方图法确定阈值,改变图像大小为(920,500),还有一点需要注意的是把图像使用灰度图表示以后,
# 要与原图片做位运算操作,要重新转化为3通道图,这一次就没有噪声点了

import datetime
import time

#——————————————————————————————————————————————————————————————————————#
start_dt = datetime.datetime.now()
print("start_datetime:", start_dt)
time.sleep(2)
for i in range(10000):
    i += 1
#——————————————————————————————————————————————————————————————————————#


import cv2
import numpy as np

# 计算灰度直方图
def calcGrayHist(grayimage):
    # 灰度图像矩阵的高,宽
    rows, cols = grayimage.shape

    # 存储灰度直方图
    grayHist = np.zeros([256], np.uint64)
    for r in range(rows):
        for c in range(cols):
            grayHist[grayimage[r][c]] += 1

    return grayHist

# 阈值分割:直方图技术法
def threshTwoPeaks(image):

    #转换为灰度图
    if len(image.shape) == 2:
        gray = image
    else:
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 计算灰度直方图
    histogram = calcGrayHist(gray)
    # 寻找灰度直方图的最大峰值对应的灰度值
    maxLoc = np.where(histogram == np.max(histogram))
    # print(maxLoc)
    firstPeak = maxLoc[0][0] #灰度值
    # 寻找灰度直方图的第二个峰值对应的灰度值
    measureDists = np.zeros([256], np.float32)
    for k in range(256):
        measureDists[k] = pow(k - firstPeak, 2) * histogram[k] #综合考虑 两峰距离与峰值
    maxLoc2 = np.where(measureDists == np.max(measureDists))
    secondPeak = maxLoc2[0][0]
    print('双峰为:',firstPeak,secondPeak)  # 181 26

    # 找到两个峰值之间的最小值对应的灰度值,作为阈值
    thresh = 0
    if firstPeak > secondPeak:  # 第一个峰值再第二个峰值的右侧
        temp = histogram[int(secondPeak):int(firstPeak)]
        minloc = np.where(temp == np.min(temp))
        thresh = secondPeak + minloc[0][0] + 1
    else:  # 第一个峰值再第二个峰值的左侧
        temp = histogram[int(firstPeak):int(secondPeak)]
        minloc = np.where(temp == np.min(temp))
        thresh = firstPeak + minloc[0][0] + 1

    # 找到阈值之后进行阈值处理,得到二值图
    threshImage_out = gray.copy()
    # 大于阈值的都设置为255
    threshImage_out[threshImage_out > thresh] = 255
    threshImage_out[threshImage_out <= thresh] = 0
    return thresh, threshImage_out

#路径--
Pep_video = "../data/People29.mp4"
Scene_video = "../data/BearScene.mp4"
Des_video = "../data/Destination.mp4"
#读取视频
Pep_Video = cv2.VideoCapture(Pep_video)
Scene_Video = cv2.VideoCapture(Scene_video)

#获取视频的频率 多少帧每秒
Fps_Pep = Pep_Video.get(cv2.CAP_PROP_FPS)
#设置视频写入的编码格式
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
#获取两个视频的宽度和高度
Pep_wid = int(Pep_Video.get(cv2.CAP_PROP_FRAME_WIDTH))
Pep_heit = int(Pep_Video.get(cv2.CAP_PROP_FRAME_HEIGHT))
# print(Pep_wid,Pep_heit)
#保存字幕后的视频
# videoWriter = cv2.VideoWriter(Des_video, fourcc, Fps_Pep, (920,500))
#把人和风景的视频都打开
frame = 0
thresh = 0
while True:
    Pepret,Pepframe = Pep_Video.read()
    Sceneret,Sceneframe = Scene_Video.read()
    if Pepret == True  and Sceneret == True :
        frame += 1
        Pepframe = cv2.resize(Pepframe,(920,500))
        Sceneframe = cv2.resize(Sceneframe,(920,500))
        img_gray = cv2.cvtColor(Pepframe, cv2.COLOR_BGR2GRAY)
        if frame == 2:  #发现第二帧的效果会比较好,第一帧有一些迷糊
            thresh, img_sep = threshTwoPeaks(Pepframe)
            print(thresh)
        threshImage_out = img_gray.copy()
        # 大于阈值的都设置为255
        threshImage_out[threshImage_out > thresh] = 255
        threshImage_out[threshImage_out <= thresh] = 0
        #人是黑色的,背景是白色的
        thresh3gate= cv2.cvtColor(threshImage_out, cv2.COLOR_GRAY2BGR)
        #通过得到的三通道灰度图,按位运算,得到嵌入图
        #得到人和白色背景
        Peo_img = cv2.bitwise_or(thresh3gate,Pepframe)
        #得到背景和白色人
        thresh3gatenot = cv2.bitwise_not(thresh3gate)
        #获取样本人的图片
        samplePeo = cv2.bitwise_and(Peo_img,thresh3gatenot)
        cv2.imshow("",samplePeo)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        cv2.imwrite('../data/Peo_model.png', samplePeo)
        Scene_img = cv2.bitwise_or(thresh3gatenot,Sceneframe)
        #嵌入
        embed_img = cv2.bitwise_and(Peo_img,Scene_img)
        # videoWriter.write(embed_img)
        print('Finish one frame')
    else:
        # videoWriter.release()
        break

#——————————————————————————————————————————————————————————————————————#
end_dt = datetime.datetime.now()
print("end_datetime:", end_dt)
print("time cost:", (end_dt - start_dt).seconds, "s")
#——————————————————————————————————————————————————————————————————————#
#it costs 23s
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

榆钱不知秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值