kuj0210 / Smart-mobile

for 2018 Creative Design project in Kumoh National Institute of Technology, department of computer engineering
4 stars 2 forks source link

General 0.1 #56

Closed ras120 closed 6 years ago

ras120 commented 6 years ago

image

파일다운

Run.zip

Run_PI_Test.zip

check.zip

PPD42NS_py.zip

온습도 센서, 먼지센서 코드는 있지만 실행은 아직 안해봄(장치 미연결 에러뜸) Vo, Vi 클래스 실행확인

import threading import cv2 import wave import threading from matplotlib import pyplot as plt import numpy as np import scipy.io.wavfile as wav from numpy.lib import stride_tricks import pylab import pyaudio import pigpio import PPD42NS import DHT22 import time

class Vi(): BREAK_AWAY = "" RETURN_BACK = "" UNTILL_BREAK = "" frame = 0 my_contours = [] st_frame = 0 out_frame = 0 sz_frame = 0 # 세이프티존 생성시 기준프레임 os_frame = 0 ob_frame = 0 # 관측 프레임 sz_size = 0 # 세이프티존 사이즈 cap = 0 vi_width = 0 #비디오 너비 vi_height = 0 #비디오 높이 contours = [] #영상처리후의 윤곽 edges = [] mx = 0 #무게중심 x좌표 my = 0 #무게중심 y좌표 sz_x = 0 #세이프티존 최상단좌측 x좌표 sz_y = 0 #세이프티존 최상단좌측Y좌표 sz_w = 0 #세이프티존 너비 sz_h = 0 #세이프티존 높이

def __init__(self,Push):
    self.BREAK_AWAY = "아이의 존이탈이 감지되었습니다!"
    self.RETURN_BACK = "아이가 Safty Zone 안으로 돌아왔습니다!"
    self.UNTILL_BREAK = "아이가 여전히 존이탈 중입니다!"
    self.mPush = Push
    self.frame = 0
    self.my_contours = []
    self.st_frame = 0
    self.out_frame = 0
    self.sz_frame = 15
    self.os_frame = 10
    self.ob_frame = 1
    self.sz_size = 100
    self.cap = 0
    self.vi_width = 0
    self.vi_height = 0
    self.contours = []
    self.edges = []
    self.mx = 0
    self.my = 0
    self.sz_x = 0
    self.sz_y = 0
    self.sz_w = 0
    self.sz_h = 0
    self.openCamera()
    #self.run()

def out(self):
    if self.mx > self.sz_x and self.mx < self.sz_x + self.sz_w and self.my > self.sz_y and self.my < self.sz_y + self.sz_h:
        return 0
    else:
        return 1

def openCamera(self):
    self.cap = cv2.VideoCapture('test2.mp4')  # 웹켐쓸거면인자 0 , 영상파일 열거면 이름 넣을것
    self.vi_width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    self.vi_height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

def getCapture(self):
    ret, self.frame = self.cap.read()
    if self.frame is None: return;
    frgray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
    kernel = np.ones((3, 3), np.float32) / 25
    dst = cv2.filter2D(frgray, -1, kernel)
    self.edges = cv2.Canny(dst, 50, 100)
    _, self.contours, _ = cv2.findContours(self.edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

def getMoment(self):
    # moment이용 무게중심을 구함
    max_area = 0;
    ci = 0
    for i in range(len(self.contours)):
        cnt = self.contours[i]
        area = cv2.contourArea(cnt)
        if (area > max_area):
            max_area = area
            ci = i
    contours = self.contours[ci]
    mmt = cv2.moments(contours)
    if mmt['m00'] != 0:
        self.mx = int(mmt['m10'] / mmt['m00'])
        self.my = int(mmt['m01'] / mmt['m00'])
    cv2.rectangle(self.frame, (int(self.mx), int(self.my)), (int(self.mx), int(self.my)), (0, 0, 255), 8)
    if self.frame is None: return;
    cv2.imshow('fgmask', self.frame)
    cv2.imshow('EDGES', self.edges)

def getSaftyZone(self):
    # 세이프티존 생성
    for i in range(0, self.vi_width):
        for j in range(0, self.vi_height):
            if self.edges[j, i] == 0:
                self.edges[j, i] = 255
            else:
                self.edges[j, i] = 0
                self.my_contours.append([i, j])
    B = np.array(self.my_contours)
    self.sz_x, self.sz_y, self.sz_w, self.sz_h = cv2.boundingRect(B)
    self.setSafttyZoneSize()
    cv2.rectangle(self.frame, (int(self.sz_x), int(self.sz_y)),
                  (int(self.sz_x + self.sz_w), int(self.sz_y + self.sz_h)), (0, 0, 255), 3)

def setSafttyZoneSize(self):
    # 세이프티존 크기 설정
    tmp_rx = self.sz_x
    tmp_ry = self.sz_y
    self.sz_x = tmp_rx + int((100 - self.sz_size) / 200 * self.sz_w)
    self.sz_y = tmp_ry + int((100 - self.sz_size) / 200 * self.sz_h)
    self.sz_w = self.sz_size / 100 * self.sz_w
    self.sz_h = self.sz_size / 100 * self.sz_h

def checkSaftyZone(self):
    # 존이탈
    if self.out() == 1:
        self.out_frame = self.out_frame + 1
    else:
        if self.out_frame > 30:
            self.out_frame = 0
            return(self.RETURN_BACK)
    if self.out_frame == 30:
        return(self.BREAK_AWAY)
    if self.out_frame > 0 and self.out_frame % 100 == 0:
        return(self.UNTILL_BREAK)
    return 0;

def checkObserveFrame(self):
    self.st_frame = self.st_frame + 1
    if self.st_frame < self.os_frame: return 1
    if self.st_frame != self.sz_frame:
        if self.st_frame % self.ob_frame != 0 and self.out_frame == 0:
            return 1
        if self.st_frame % 5 != 0:
            return 1
    return 0

def run(self):
    while(True):
        if self.checkObserveFrame() == 1 :
           continue
        self.getCapture()
        self.getMoment()
        if self.st_frame == self.sz_frame:
            self.getSaftyZone()
        MSG = self.checkSaftyZone()
        if MSG != 0 :
            self.mPush.insertMSG(MSG)
        k = cv2.waitKey(30) & 0xff
        if k == 27:
            break
    self.cap.release()
    cv2.destroyAllWindows()

class Vo(): FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 44100 CHUNK = 1024 RECORD_SECONDS = 5 # 녹음 길이(초) DEVICE_INDEX = 1 WAVE_OUTPUT_FILENAME = "file.wav" Recode_Value = 1000 # 큰 소리 값 bindo_Value = 0.6

여기까지 recode 관련 녹음 환경 설정

Cry_Value = 1000
Cut_Value = 100
Sick_Value = 50000
Hungry_Value = 20000
#Sleepy_Value = 0

# 여기까지 detection 관련

def __init__(self,Push):
    self.mPush =Push

def run(self):
    while(True):
        detection_flag = self.recode()
        if detection_flag:
            self.detection2()

def recode(self):
    audio = pyaudio.PyAudio()
    stream = audio.open(
        format=self.FORMAT,
        channels=self.CHANNELS,
        rate=self.RATE,
        input=True,
        input_device_index=self.DEVICE_INDEX,
        frames_per_buffer=self.CHUNK)
    frames = []

    # 첫번째 프레임 확인
    data = stream.read(self.CHUNK)
    check = pylab.fromstring(data, 'int16')
    if (sum(abs(check)) / len(check)) < self.Recode_Value:
        stream.stop_stream()
        stream.close()
        audio.terminate()
        return False
    print("recode...")
    for i in range(1, int(self.RATE / self.CHUNK * self.RECORD_SECONDS)):
        data = stream.read(self.CHUNK)
        frames.append(data)

    stream.stop_stream()
    stream.close()
    audio.terminate()

    waveFile = wave.open(self.WAVE_OUTPUT_FILENAME, 'wb')
    waveFile.setnchannels(self.CHANNELS)
    waveFile.setsampwidth(audio.get_sample_size(self.FORMAT))
    waveFile.setframerate(self.RATE)
    waveFile.writeframes(b''.join(frames))
    waveFile.close()
    return True

# short time fourier transform of audio signal
def stft(self,sig, frameSize, overlapFac=0.5, window=np.hanning):
    # sig = signal frameSize = 2 ** 10

    win = window(frameSize)
    hopSize = int(frameSize - np.floor(overlapFac * frameSize))

    # zeros at beginning (thus center of 1st window should be for sample nr. 0)
    samples = np.append(np.zeros(int(np.floor(frameSize / 2.0))), sig)
    # cols for windowing
    cols = np.ceil((len(samples) - frameSize) / float(hopSize)) + 1
    # zeros at end (thus samples can be fully covered by frames)
    samples = np.append(samples, np.zeros(frameSize))

    frames = stride_tricks.as_strided(samples, shape=(int(cols), frameSize),
                                      strides=(samples.strides[0] * hopSize, samples.strides[0])).copy()
    frames *= win

    return np.fft.rfft(frames)

# scale frequency axis logarithmically
def logscale_spec(self,spec, sr=44100, factor=20.):
    timebins, freqbins = np.shape(spec)

    scale = np.linspace(0, 1, freqbins) ** factor
    scale *= (freqbins - 1) / max(scale)
    scale = np.unique(np.round(scale))

    # create spectrogram with new freq bins
    newspec = np.complex128(np.zeros([timebins, len(scale)]))
    for i in range(0, len(scale)):
        if i == len(scale) - 1:
            newspec[:, i] = np.sum(spec[:, int(scale[i]):], axis=1)
        else:
            newspec[:, i] = np.sum(spec[:, int(scale[i]):int(scale[i + 1])], axis=1)

    # list center freq of bins
    allfreqs = np.abs(np.fft.fftfreq(freqbins * 2, 1. / sr)[:freqbins + 1])
    freqs = []
    for i in range(0, len(scale)):
        if i == len(scale) - 1:
            freqs += [np.mean(allfreqs[int(scale[i]):])]
        else:
            freqs += [np.mean(allfreqs[int(scale[i]):int(scale[i + 1])])]

    return newspec, freqs

def detection2(self):
    # sr , sample
    samplerate, samples = wav.read(self.WAVE_OUTPUT_FILENAME)
    binsize = 2 ** 10

    #class 안에와 class 밖에 두 함수 다 있습니다.
    #self쓰면 안돌고 self안쓰면 잘돕니당.

    s = self.stft(samples, binsize)
    sshow, freq = self.logscale_spec(s, sr=samplerate, factor=1.0)

    # amplitude to decibel
    ims = 20. * np.log10(np.abs(sshow) / 10e-6)
    # ims = 20. * np.log10(np.abs(sshow))
    timebins, freqbins = np.shape(ims)

    time = ((timebins * len(samples) / timebins) + (0.5 * binsize)) / samplerate
    timei = ((len(samples) / timebins) + (0.5 * binsize)) / samplerate
    timei /= 2

    maxnum = 0
    fr25 = 0
    tmp = 0
    fullcount = 0

    for i in range(timebins):
        for j in range(freqbins):
            if i == 0:
                if freq[j] < 2500:
                    tmp = j
            if ims[i][j] < 200:
                ims[i][j] = 0
            else:
                maxnum += 1
                fullcount += ims[i][j]

    ti = 0
    maxval = 0
    maxnum2500 = 0
    fullcount2500 = 0
    t_if = True
    tcheck = 0
    for i in range(timebins):
        for j in range(0, tmp + 1):
            if maxval < ims[i][j]:
                maxval = ims[i][j]
                ti = i
            if ims[i][j] >= 200:
                maxnum2500 += 1
                fullcount2500 += ims[i][j]
                if t_if != i:
                    t_if = i
                    tcheck += 1

    cry_bindo = tcheck/timebins  * 100
    cry_volum = maxnum2500/timebins * 100
    if cry_volum > 10:
        result = "울어요"

    if tcheck/timebins  * 100 < 20:
        result += ", 졸려요"
    else :
        if cry_volum < 60:
            result += ", 아파요"
        else:
            result += ", 배고파요"

    self.mPush.insertMSG(result)

class Info(): def init(self, Push): self.mPush = Push

def get_Dust(self):
    g, r, c = self.Dust_Run()
    self.mPush.insertMSG("gpio={} ratio={:.1f} conc={} pcs per 0.01 cubic foot".format(g, r, int(c)))

def get_DHT(self):
    h, t = self.DHT_Run()
    self.mPush.insertMSG("습도 : {" + h + "}  온도 : {" + t + "}")

def run(self):
    while True:
        g, r ,c = self.Dust_Run()
        if r > 0.2:
            self.mPush.insertMSG("gpio={} ratio={:.1f} conc={} pcs per 0.01 cubic foot".format(g, r, int(c)))
        h, t = self.DHT_Run()
        if h > 60 or t >30:
            self.mPush.insertMSG("습도 : " + h + "온도 : " + t)

def Dust_Run(self):
    pi = pigpio.pi()
    s = PPD42NS.sensor(pi, 24)
    g, r, c = s.read()
    #msg = "gpio={" + g + "} ratio={" + r + "} conc={" + int(c) + "} pcs per 0.01 cubic foot"
    pi.stop()  # Disconnect from Pi.
    #self.mPush.insertMSG("gpio={} ratio={:.1f} conc={} pcs per 0.01 cubic foot".format(g, r, int(c)))
    return g, r, c

def DHT_Run(self):
    INTERVAL = 3
    pi = pigpio.pi()
    s = DHT22.sensor(pi, 22, LED=16, power=8)
    r = 0
    next_reading = time.time()

    r += 1
    s.trigger()
    time.sleep(0.2)
    print("{} {} {} {:3.2f} {} {} {} {}".format(
        r, s.humidity(), s.temperature(), s.staleness(),
        s.bad_checksum(), s.short_message(), s.missing_message(),
        s.sensor_resets()))

    next_reading += INTERVAL
    time.sleep(next_reading - time.time())  # Overall INTERVAL second polling.

    s.cancel()
    pi.stop()
    #self.mPush.insertMSG("습도 : {" + h + "}  온도 : {" + t + "}")
    return s.humidity(), s.temperature()

class Push(threading.Thread): def init(self): self.sem_using = threading.Semaphore(1) # 1명만 쓸것 self.sem_emp = threading.Semaphore(0) self.Q=[] self.mvi = Vi(self) self.mvo = Vo(self) self.VIth =threading.Thread(target=self.mvi.run) self.VOth = threading.Thread(target=self.mvo.run) self.mInfo = Info(self)

def insertMSG(self,str):
    self.sem_using.acquire()
    self.Q.append(str)
    print("--------------------in 관측자[%s]삽입완료"%str)
    self.sem_using.release()
    self.sem_emp.release() # 세마포어 값 증가

def getMSG(self):
    self.sem_emp.acquire()
    self.sem_using.acquire()
    msg =self.Q[0]
    del self.Q[0]
    self.sem_using.release()
    return msg

def run(self):
    self.VIth.start()
    self.VOth.start()
    #self.mInfo.get_Dust()
    #self.mInfo.get_DHT()
    while(True):
        print("in 관찰자[%s]"%( self.getMSG()) )

p = Push() p.run()

ras120 commented 6 years ago

image