Найти - Пользователи
Полная версия: Как определить полупрозрачный логотип на видео?
Начало » Python для экспертов » Как определить полупрозрачный логотип на видео?
1
alex1306
Здравствуйте.

Делаю скрипт, который определит координаты и размер логотипа на видео.

В качестве теста я использовал короткие видео

https://dl.dropbox.com/u/100403694/1.mp4
https://dl.dropbox.com/u/100403694/2.mp4
https://dl.dropbox.com/u/100403694/3.mp4
https://dl.dropbox.com/u/100403694/4.mp4

Сам скрипт:

#!/usr/bin/env python
# -*- coding= utf-8 -*-
import sys
import cv2
import numpy as np
from time import clock
tracked_contours = []
class Contour():
    def __init__(self, contour):
        self.data = get_contour_data(contour)
        self.pixel_error = 5
        self.score = 0
    def __eq__(self, other):
        for i in range(len(self.data)):
            if abs(self.data[i]-other.data[i]) > self.pixel_error:
                return False
        return True
def get_contour_data(contour):
    xx = np.array([ a[0][0] for a in contour ])
    yy = np.array([ a[0][1] for a in contour ])
    return [xx.min(), yy.min(), xx.max(), yy.max()]
def check_contours(contours, count, img):
    for tracked_contour in tracked_contours:
        if count % 2 == 0:
            tracked_contour.score -= 1
        if tracked_contour.score < 0:
            tracked_contours.remove(tracked_contour)
    for contour in contours:
        c = Contour(contour)
        if c in tracked_contours:
            i = tracked_contours.index(c)
            tracked_contours[i].score += 1
            cv2.rectangle(img, (tracked_contours[i].data[0], \
                tracked_contours[i].data[1]), (tracked_contours[i].data[2], \
                tracked_contours[i].data[3]), (tracked_contours[i].score*10, tracked_contours[i].score*5, tracked_contours[i].score), tracked_contours[i].score)
            if tracked_contours[i].score > 40:
                return True, c
        else: tracked_contours.append(c)
    return False, None
def drawContours(contours, img):
    for contour in contours:
        data = get_contour_data(contour)
        cv2.rectangle(img, (data[0], data[1]), (data[2], data[3]), (255,0,0))
def detect(file_name):
    c = cv2.VideoCapture(file_name)
    _,f = c.read()
    f = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)
    avg = np.float32(f)
    cv2.namedWindow("img")
    cv2.namedWindow("grey")
    cv2.namedWindow("avg")
    t = 0
    count = 0
    while(1):
        if t % 5 != 0:
            _,f = c.read()
            if f == None:
                exit(1)
            t+=1
            continue
        count += 1
        t += 1
        _,f = c.read()
        if f == None:
            exit(1)
        cv2.imshow('img',f)
        f = np.float32(cv2.cvtColor(f, cv2.COLOR_BGR2GRAY))
        cv2.accumulateWeighted(f, avg, 0.005)
        res = cv2.convertScaleAbs(avg)
        cv2.imshow('grey',res)
        thresh, res = cv2.threshold(res, 200, 255, cv2.THRESH_BINARY)
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(40,40))
        mat = cv2.dilate(res,kernel)
        contours, hierarchy = cv2.findContours(mat,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)
        res = cv2.cvtColor(res, cv2.COLOR_GRAY2BGR)
        a,b = check_contours(contours, count, res)
        if a == True:
            cv2.rectangle(res, (b.data[0], b.data[1]), (b.data[2], b.data[3]), (0,255,0), 5)
            cv2.imshow('avg',res)
            k = cv2.waitKey(5000)
            break
        #drawContours(contours, res)
        cv2.imshow('avg',res)
        k = cv2.waitKey(20)
        if k == 27:
            break
    cv2.destroyAllWindows()
    c.release()
class Detector():
    ADD_WEIGHT = 0.005
    MORPH_WEIGHT = (40, 40)
    TRESHOLD = 200
    MAX_SCORE = 40
    def __init__(self, frame):
        self.tick = 0
        self._initAvg(frame)
        self._isDetected = False
        self.trackedContours = []
    def update(self, frame):
        self.tick += 1
        self._updateAvg(frame)
        res = self._getCurrentAvgBinary()
        res = self._applyDilatation(res)
        contours = self._getContours(res)
        self._updateTrackedContours(contours)
    def isDetected(self):
        return self._isDetected
    def getCoords(self):
        max_score = 0
        contour = None
        for trackedContour in self.trackedContours:
            if max_score < trackedContour.score:
                max_score = trackedContour.score
                contour = trackedContour
        if contour != None:
            return [(contour.data[0], contour.data[1]), (contour.data[2], contour.data[3])]
        return None
    def _updateTrackedContours(self, contours):
        for trackedContour in self.trackedContours:
            if self.tick % 2 == 0:
                trackedContour.score -= 1
            if trackedContour.score < 0:
                self.trackedContours.remove(trackedContour)
        for contour in contours:
            c = Contour(contour)
            if c in self.trackedContours:
                i = self.trackedContours.index(c)
                self.trackedContours[i].score += 1
                if self.trackedContours[i].score > Detector.MAX_SCORE:
                    self._isDetected = True
            else: self.trackedContours.append(c)
    def _initAvg(self, frame):
        f = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        self.avg = np.float32(f)
    def _updateAvg(self, frame):
        frame = np.float32(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY))
        cv2.accumulateWeighted(frame, self.avg, Detector.ADD_WEIGHT)
    def _getCurrentAvgBinary(self):
        res = cv2.convertScaleAbs(self.avg)
        _,res = cv2.threshold(res, Detector.TRESHOLD, 255, cv2.THRESH_BINARY)
        return res            
    def _applyDilatation(self, frame):
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, Detector.MORPH_WEIGHT)
        return cv2.dilate(frame, kernel)
    def _getContours(self, frame):
        contours,_ = cv2.findContours(frame, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        return contours
def process(fileName):
#    cv2.namedWindow("frame")
    stream = cv2.VideoCapture(fileName)
    _,frame = stream.read()
    detector = Detector(frame)
    t = 0
    while(1):
        if t % 5 != 0:
            _,frame = stream.read()
            if frame == None:
                return detector.getCoords()
            t+=1
            continue
        t += 1
        _,frame = stream.read()
        if frame == None:
            return detector.getCoords()
        detector.update(frame)
        if detector.isDetected():
            return detector.getCoords()
#            returncv2.rectangle(frame, coords[0], coords[1], (0,255,0), 5)
#            cv2.imshow('frame',frame)
#            cv2.waitKey(5000)
            break
#    cv2.destroyAllWindows()
    stream.release()
if __name__ == "__main__":
    fileName = sys.argv[1]
    #detect(fileName)
    print process(fileName)


Обработка видео 2.mp4 приносит нулевой результат. И вообще полупрозрачные логотипы скрипт обрабатывает некорректно. Но остальные видео обрабатываются правильно.

Возможно кто-то уже делал подобные проекты. В чем может быть причина?

Скрипт запускаю из консоли на vps: script.py 2.mp4
Логотипа на видео я не вижу и никаким иным образом, кроме запуска скрипта его определить не могу. Автодетекция - замысел скрипта. Любой ручной труд по определению лого исключается.
Shaman
Навскидку: где-то нужно задавать порог. Логотип - зона с минимальными изменениями цвета и яркости.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB