Skip to content

Instantly share code, notes, and snippets.

@Vitaleks-project
Last active August 29, 2015 13:57
Show Gist options
  • Save Vitaleks-project/9790724 to your computer and use it in GitHub Desktop.
Save Vitaleks-project/9790724 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'raudio'
require 'OpenCV'
class MotionDetector
def onChange(self, val) #Зворотній виклик коли користувач змінює поріг чутливості.
self.threshold = val
end
def self.initialize(threshold = 25, doRecord = true, showWindows = true)
self.absdiff_frame = false
self.writer = false
self.font = false
self.doRecord = doRecord #Методи запису рухомого об'єкту
self.show = showWindows
self.frame = false
self.capture=OpenCV::CaptureFromCAM(0)
self.frame = OpenCV::QueryFrame(self.capture) #Захоплення кадру після ініціалізації відео
if OpenCV::doRecord.kind_of?(FalseClass)
self.initRecorder()
end
self.gray_frame = OpenCV::CreateImage(OpenCV::GetSize(self.frame), OpenCV::IPL_DEPTH_8U, 1)
self.average_frame = OpenCV::CreateImage(OpenCV::GetSize(self.frame), OpenCV::IPL_DEPTH_32F, 3)
self.absdiff_frame = false
self.previous_frame = false
self.surface = self.frame.width * self.frame.height
self.currentsurface = 0
self.currentcontours = false
self.threshold = threshold
self.isRecording = false
self.trigger_time = 0 #Фіксація часу останнього виявлення руху
if showWindows
OpenCV::NamedWindow("Video Motion")
OpenCV::CreateTrackbar("Sensitivity: ", "Image", self.threshold, 10, self.onChange)
end
end
def initRecorder(self) #Ініціалізація запису відео
codec = OpenCV::CV_FOURCC('M', 'J', 'P', 'G')
#FPS встановлено 30 для моєї камери (кількість кадрів у секунду)
self.writer = OpenCV::CreateVideoWriter(Time.now.strftime("%Y-%m-%d %H:%M:%S")+".wmv", codec, 30, OpenCV::GetSize(self.frame), 1)
self.font = OpenCV::InitFont(OpenCV::CV_FONT_HERSHEY_SIMPLEX, 1, 1, 0, 2, 8)
end
def processImage(current_frame)
OpenCV::Smooth(current_frame, current_frame) #Видалення помилкових спрацювань
if self.absdiff_frame #Порівнюємо кадри клонуючи їх
self.absdiff_frame = OpenCV::CloneImage(curframe)
self.previous_frame = OpenCV::CloneImage(curframe)
OpenCV::Convert(current_frame, self.average_frame)
else
OpenCV::RunningAvg(current_frame, self.average_frame, 0.05) #Обчислення середнього значення
OpenCV::Convert(self.average_frame, self.previous_frame)
#Розрахування середнього значення після порівння absDiff
OpenCV::AbsDiff(current_frame, self.previous_frame, self.absdiff_frame)
#Конвертування зображення в сірий колір (інакше не можна використати поріг)
OpenCV::CvtColor(self.absdiff_frame, self.gray_frame, OpenCV.CV_RGB2GRAY)
OpenCV::Threshold(self.gray_frame, self.gray_frame, 50, 255, OpenCV.CV_THRESH_BINARY)
#Для отримання візуального виділення рухів
OpenCV::Dilate(self.gray_frame, self.gray_frame, false, 15)
OpenCV::Erode(self.gray_frame, self.gray_frame, false, 10)
end
end
def run(self)
@started = Time.now()
while true
@currentframe = OpenCV::QueryFrame(self.capture)
@instant = Time.now() #Часова мітка
self.processImage(@currentframe) #Обробка зображення
if !self.isRecording
if self.somethingHasMoved()
self.trigger_time = @instant #Оновлення часу запуску
#Очікуємо 5 секунд після запуску камери для стабілізації освітлення і т.д.
if @instant > @started + 5
puts "--------- Something is moving! -----------"
chunk = 1024
sound = wave.open(r"/home/vitaliyjorzh/diplom/home9.wav","rb")
data = sound.readframes(chunk)
audio = RAudio::Audio_init()
stream = audio.open(format = audio.get_format_from_width(sound.getsampwidth()),
channels = sound.getnchannels(),
rate = sound.getframerate(),
output = true)
data = sound.readframes(chunk)
while data != ''
stream.write(data)
data = sound.readframes(chunk)
stream.stop_stream()
stream.close()
p.terminate()
#Встановлення isRecording = true тільки якщо ми записуємо відео після детектування руху
if self.doRecord
self.isRecording = true
end
end
end
OpenCV::DrawContours (currentframe, self.currentcontours, (0, 0, 255), (0, 255, 0), 1, 2, cv.CV_FILLED)
else
#Запис відео протягом 5 секунд
if @instant >= self.trigger_time + 5
puts "--------- Stop recording ----------"
self.isRecording = false
else
#Встановення дати у вікно
OpenCV::PutText(currentframe, "Motion detect, recording video", (45,50),self.font, 0)
OpenCV::WriteFrame(self.writer, currentframe)
end
end
if self.show
OpenCV::ShowImage("Image", currentframe)
end
key = OpenCV::WaitKey(1) % 0x100
if(key == 27 || key == 10) #Вихід при натисканні на "Esc"
break
end
end
end
end
def somethingHasMoved(self)
#Пошук контурів
@storage = OpenCV::CreateMemStorage(0)
@contours = OpenCV::FindContours(self.gray_frame,
storage,
OpenCV::CV_RETR_EXTERNAL,
OpenCV::CV_CHAIN_APPROX_SIMPLE)
self.currentcontours = @contours #Збереження контурів
while @contours
self.currentsurface += OpenCV::ContourArea(@contours)
@contours = @contours.h_next()
#Обчислення середньої площі контуру від загального розміру
avg = (self.currentsurface*100)/self.surface
self.currentsurface = 0
if avg > self.threshold
return true
else
return false
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment