模糊检测SMD2代码,从视频流中抽取某段间隔最清晰的K张图片

smd2 灰度差分乘积法,速度感觉略慢,因为要遍历每个像素,一个像素与右边像素的差sub1 及与下面像素的差sub2,然后求积,score = abs(sub1)*abs(sub2), 将所有像素的score 累加 得出scores。 scores值越大说明边缘越多,图像越清晰。 

下面将smd2封装成一个类。

其中def saveImage(self, imageList): # 保存清晰图片 可以选择注释掉,只是保存图片到本地而已。

该类需要传入一组图片的list,设置需要求出的最清晰的topK 张图片, 求的方法就是在一个scores 数组中求topk问题,直接用最小堆就行,python代码简单粗暴到不行,就一行语句!!

import os
import cv2
import numpy as np
import heapq

#global temi
#temi = 0

class SMD2:
    def __init__(self, imageList, topk=3):
        print("SMD2模糊检测 ")
        self.imageList = imageList # 图片list
        self.topk = topk # 检测最不模糊的k张

    def TestSMD2(self):
        scores = []
        for i in range(len(self.imageList)):
            score = self.SMD2Work(self.imageList[i])
            print("分数判定,处理第 ", i, " 张图片, score = ", score)
            scores.append(score)
        maxScoreIndex = self.getListMaxNumIndex(scores, self.topk)
        topkClearImageList = [] # 存放最清晰的图片list
        for j in range(len(maxScoreIndex)):
            print("分数最大的图片 ", j, " ,score = ", scores[maxScoreIndex[j]])
            topkClearImageList.append(self.imageList[maxScoreIndex[j]])

        self.saveImage(topkClearImageList) # 保存筛选出来的图片 
        return topkClearImageList

    def SMD2Work(self, image): # 灰度差分乘积,速度慢
        height, width = image.shape[:2]  
        image = cv2.resize(image, (int(width/2.2), int(height/2.2)))
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        f = np.matrix(gray) / 255.0 # 返回矩阵
        x, y = f.shape
        score = 0
        for i in range(x - 1):
            for j in range(y - 1):
                score += np.abs(f[i+1,j]-f[i,j])*np.abs(f[i,j]-f[i,j+1])
        return score

    def getListMaxNumIndex(self, num_list, topk): # 返回最大k个值的下标
        max_num_index = map(num_list.index, heapq.nlargest(topk, num_list))
        
        #max_num_index = map(num_list.index, heapq.nsmallest(topk,num_list))
        max_num_index = list(max_num_index) # 需转成list
        return max_num_index

    def saveImage(self, imageList): # 保存清晰图片
        #global temi
        saveDir = "./SMD2Detection/"
        if not os.path.exists(saveDir):
            os.makedirs(saveDir)
        for i in range(len(imageList)):
            #imgPath = saveDir + str(temi) + ".jpg"
            imgPath = saveDir + str(i) + ".jpg"
            cv2.imwrite(imgPath, imageList[i])
            #print("保存第 ", temi, " 张最清晰的图片")
            print("保存第 ", i, " 张最清晰的图片")
            #temi += 1
        return

另外的代码就是从一个视频中隔一段时间抽若干张图片出来,比如隔10秒抽20张图片出来,然后再从这20张图片选最清晰的to pK张图片,就是调用上面这个类。

代码随便写的。

if __name__ == "__main__":
    videoP = "/Users/cmq/Desktop/Internship/ZCW_headDetection/video/桂_1/test2.avi"
    cap = cv2.VideoCapture(videoP)
    ret = True
    # 每隔perframe张抽相邻getframe张,找出topk张最清晰的,视频走完stopframe帧后终止
    count = 0
    stopframe = 1000
    topk = 3
    perframe = 100 
    getframe = 10
    imgList = []
    append_flag = True
    while(cap.isOpened and ret and count != stopframe):
        ret, frame = cap.read()
        if count % perframe == 0:
            append_flag = True
        
        if append_flag:
            imgList.append(frame)
            if count % perframe == getframe:
                append_flag = False
                smd2 = SMD2(imgList)  # 检测
                smd2.TestSMD2()
                imgList = []
        
        count += 1

 最主要是上面的smd2类~

smd2 = SMD2(imgList)  # 创建对象,默认topk=3

 smd2.TestSMD2() # 开始计算

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值