text:
import numpy as np
import pandas as pd
import re
from itertools import chain, combinations
from nltk.tokenize import word_tokenize
from spellchecker import SpellChecker
from nltk.stem import WordNetLemmatizer
from tqdm import tqdm

tqdm.pandas()

# https://stackoverflow.com/a/34682849
def untokenize(words):
    """Untokenizing a text undoes the tokenizing operation, restoring
    punctuation and spaces to the places that people expect them to be.
    Ideally, `untokenize(tokenize(text))` should be identical to `text`,
    except for line breaks.
    """
    text = ' '.join(words)
    step1 = text.replace("`` ", '"').replace(" ''", '"').replace('. . .', '...')
    step2 = step1.replace(" ( ", " (").replace(" ) ", ") ")
    step3 = re.sub(r' ([.,:;?!%]+)([ \'"`])', r"\1\2", step2)
    step4 = re.sub(r' ([.,:;?!%]+)$', r"\1", step3)
    step5 = step4.replace(" '", "'").replace(" n't", "n't").replace(
        "can not", "cannot")
    step6 = step5.replace(" ` ", " '")
    #step7 = re.sub(r'([a-zA-Z])\1{3,}', r'\1\1', step6) # new
    return step6.strip()

# https://stackoverflow.com/a/47091490
def decontracted(phrase):
    """Convert contractions like "can't" into "can not"
    """
    # specific
    phrase = re.sub(r"won\'t", "will not", phrase)
    phrase = re.sub(r"can\'t", "can not", phrase)

    # general
    #phrase = re.sub(r"n't", " not", phrase) # resulted in "ca not" when sentence started with "can't"
    phrase = re.sub(r"\'re", " are", phrase)
    phrase = re.sub(r"\'s", " is", phrase)
    phrase = re.sub(r"\'d", " would", phrase)
    phrase = re.sub(r"\'ll", " will", phrase)
    phrase = re.sub(r"\'t", " not", phrase)
    phrase = re.sub(r"\'ve", " have", phrase)
    phrase = re.sub(r"\'m", " am", phrase)
    return phrase

# https://github.com/rishabhverma17/sms_slang_translator/blob/master/slang.txt
slang_abbrev_dict = {
    'AFAIK': 'As Far As I Know',
    'AFK': 'Away From Keyboard',
    'ASAP': 'As Soon As Possible',
    'ATK': 'At The Keyboard',
    'ATM': 'At The Moment',
    'A3': 'Anytime, Anywhere, Anyplace',
    'BAK': 'Back At Keyboard',
    'BBL': 'Be Back Later',
    'BBS': 'Be Back Soon',
    'BFN': 'Bye For Now',
    'B4N': 'Bye For Now',
    'BRB': 'Be Right Back',
    'BRT': 'Be Right There',
    'BTW': 'By The Way',
    'B4': 'Before',
    'B4N': 'Bye For Now',
    'CU': 'See You',
    'CUL8R': 'See You Later',
    'CYA': 'See You',
    'FAQ': 'Frequently Asked Questions',
    'FC': 'Fingers Crossed',
    'FWIW': 'For What It\'s Worth',
    'FYI': 'For Your Information',
    'GAL': 'Get A Life',
    'GG': 'Good Game',
    'GN': 'Good Night',
    'GMTA': 'Great Minds Think Alike',
    'GR8': 'Great!',
    'G9': 'Genius',
    'IC': 'I See',
    'ICQ': 'I Seek you',
    'ILU': 'I Love You',
    'IMHO': 'In My Humble Opinion',
    'IMO': 'In My Opinion',
    'IOW': 'In Other Words',
    'IRL': 'In Real Life',
    'KISS': 'Keep It Simple, Stupid',
    'LDR': 'Long Distance Relationship',
    'LMAO': 'Laugh My Ass Off',
    'LOL': 'Laughing Out Loud',
    'LTNS': 'Long Time No See',
    'L8R': 'Later',
    'MTE': 'My Thoughts Exactly',
    'M8': 'Mate',
    'NRN': 'No Reply Necessary',
    'OIC': 'Oh I See',
    'OMG': 'Oh My God',
    'PITA': 'Pain In The Ass',
    'PRT': 'Party',
    'PRW': 'Parents Are Watching',
    'QPSA?': 'Que Pasa?',
    'ROFL': 'Rolling On The Floor Laughing',
    'ROFLOL': 'Rolling On The Floor Laughing Out Loud',
    'ROTFLMAO': 'Rolling On The Floor Laughing My Ass Off',
    'SK8': 'Skate',
    'STATS': 'Your sex and age',
    'ASL': 'Age, Sex, Location',
    'THX': 'Thank You',
    'TTFN': 'Ta-Ta For Now!',
    'TTYL': 'Talk To You Later',
    'U': 'You',
    'U2': 'You Too',
    'U4E': 'Yours For Ever',
    'WB': 'Welcome Back',
    'WTF': 'What The Fuck',
    'WTG': 'Way To Go!',
    'WUF': 'Where Are You From?',
    'W8': 'Wait',
    '7K': 'Sick:-D Laugher'
}

def unslang(text):
    """Converts text like "OMG" into "Oh my God"
    """
    if text.upper() in slang_abbrev_dict.keys():
        return slang_abbrev_dict[text.upper()]
    else:
        return text

# https://gist.github.com/sebleier/554280
stopwords = [
    "a", "about", "above", "after", "again", "against", "ain", "all", "am",
    "an", "and", "any", "are", "aren", "aren't", "as", "at", "be", "because",
    "been", "before", "being", "below", "between", "both", "but", "by", "can",
    "couldn", "couldn't", "d", "did", "didn", "didn't", "do", "does", "doesn",
    "doesn't", "doing", "don", "don't", "down", "during", "each", "few", "for",
    "from", "further", "had", "hadn", "hadn't", "has", "hasn", "hasn't", "have",
    "haven", "haven't", "having", "he", "her", "here", "hers", "herself", "him",
    "himself", "his", "how", "i", "if", "in", "into", "is", "isn", "isn't",
    "it", "it's", "its", "itself", "just", "ll", "m", "ma", "me", "mightn",
    "mightn't", "more", "most", "mustn", "mustn't", "my", "myself", "needn",
    "needn't", "no", "nor", "not", "now", "o", "of", "off", "on", "once",
    "only", "or", "other", "our", "ours", "ourselves", "out", "over", "own",
    "re", "s", "same", "shan", "shan't", "she", "she's", "should", "should've",
    "shouldn", "shouldn't", "so", "some", "such", "t", "than", "that",
    "that'll", "the", "their", "theirs", "them", "themselves", "then", "there",
    "these", "they", "this", "those", "through", "to", "too", "under", "until",
    "up", "ve", "very", "was", "wasn", "wasn't", "we", "were", "weren",
    "weren't", "what", "when", "where", "which", "while", "who", "whom", "why",
    "will", "with", "won", "won't", "wouldn", "wouldn't", "y", "you", "you'd",
    "you'll", "you're", "you've", "your", "yours", "yourself", "yourselves",
    "could", "he'd", "he'll", "he's", "here's", "how's", "i'd", "i'll", "i'm",
    "i've", "let's", "ought", "she'd", "she'll", "that's", "there's", "they'd",
    "they'll", "they're", "they've", "we'd", "we'll", "we're", "we've",
    "what's", "when's", "where's", "who's", "why's", "would", "able", "abst",
    "accordance", "according", "accordingly", "across", "act", "actually",
    "added", "adj", "affected", "affecting", "affects", "afterwards", "ah",
    "almost", "alone", "along", "already", "also", "although", "always",
    "among", "amongst", "announce", "another", "anybody", "anyhow", "anymore",
    "anyone", "anything", "anyway", "anyways", "anywhere", "apparently",
    "approximately", "arent", "arise", "around", "aside", "ask", "asking",
    "auth", "available", "away", "awfully", "b", "back", "became", "become",
    "becomes", "becoming", "beforehand", "begin", "beginning", "beginnings",
    "begins", "behind", "believe", "beside", "besides", "beyond", "biol",
    "brief", "briefly", "c", "ca", "came", "cannot", "can't", "cause", "causes",
    "certain", "certainly", "co", "com", "come", "comes", "contain",
    "containing", "contains", "couldnt", "date", "different", "done",
    "downwards", "due", "e", "ed", "edu", "effect", "eg", "eight", "eighty",
    "either", "else", "elsewhere", "end", "ending", "enough", "especially",
    "et", "etc", "even", "ever", "every", "everybody", "everyone", "everything",
    "everywhere", "ex", "except", "f", "far", "ff", "fifth", "first", "five",
    "fix", "followed", "following", "follows", "former", "formerly", "forth",
    "found", "four", "furthermore", "g", "gave", "get", "gets", "getting",
    "give", "given", "gives", "giving", "go", "goes", "gone", "got", "gotten",
    "h", "happens", "hardly", "hed", "hence", "hereafter", "hereby", "herein",
    "heres", "hereupon", "hes", "hi", "hid", "hither", "home", "howbeit",
    "however", "hundred", "id", "ie", "im", "immediate", "immediately",
    "importance", "important", "inc", "indeed", "index", "information",
    "instead", "invention", "inward", "itd", "it'll", "j", "k", "keep", "keeps",
    "kept", "kg", "km", "know", "known", "knows", "l", "largely", "last",
    "lately", "later", "latter", "latterly", "least", "less", "lest", "let",
    "lets", "like", "liked", "likely", "line", "little", "'ll", "look",
    "looking", "looks", "ltd", "made", "mainly", "make", "makes", "many", "may",
    "maybe", "mean", "means", "meantime", "meanwhile", "merely", "mg", "might",
    "million", "miss", "ml", "moreover", "mostly", "mr", "mrs", "much", "mug",
    "must", "n", "na", "name", "namely", "nay", "nd", "near", "nearly",
    "necessarily", "necessary", "need", "needs", "neither", "never",
    "nevertheless", "new", "next", "nine", "ninety", "nobody", "non", "none",
    "nonetheless", "noone", "normally", "nos", "noted", "nothing", "nowhere",
    "obtain", "obtained", "obviously", "often", "oh", "ok", "okay", "old",
    "omitted", "one", "ones", "onto", "ord", "others", "otherwise", "outside",
    "overall", "owing", "p", "page", "pages", "part", "particular",
    "particularly", "past", "per", "perhaps", "placed", "please", "plus",
    "poorly", "possible", "possibly", "potentially", "pp", "predominantly",
    "present", "previously", "primarily", "probably", "promptly", "proud",
    "provides", "put", "q", "que", "quickly", "quite", "qv", "r", "ran",
    "rather", "rd", "readily", "really", "recent", "recently", "ref", "refs",
    "regarding", "regardless", "regards", "related", "relatively", "research",
    "respectively", "resulted", "resulting", "results", "right", "run", "said",
    "saw", "say", "saying", "says", "sec", "section", "see", "seeing", "seem",
    "seemed", "seeming", "seems", "seen", "self", "selves", "sent", "seven",
    "several", "shall", "shed", "shes", "show", "showed", "shown", "showns",
    "shows", "significant", "significantly", "similar", "similarly", "since",
    "six", "slightly", "somebody", "somehow", "someone", "somethan",
    "something", "sometime", "sometimes", "somewhat", "somewhere", "soon",
    "sorry", "specifically", "specified", "specify", "specifying", "still",
    "stop", "strongly", "sub", "substantially", "successfully", "sufficiently",
    "suggest", "sup", "sure", "take", "taken", "taking", "tell", "tends", "th",
    "thank", "thanks", "thanx", "thats", "that've", "thence", "thereafter",
    "thereby", "thered", "therefore", "therein", "there'll", "thereof",
    "therere", "theres", "thereto", "thereupon", "there've", "theyd", "theyre",
    "think", "thou", "though", "thoughh", "thousand", "throug", "throughout",
    "thru", "thus", "til", "tip", "together", "took", "toward", "towards",
    "tried", "tries", "truly", "try", "trying", "ts", "twice", "two", "u", "un",
    "unfortunately", "unless", "unlike", "unlikely", "unto", "upon", "ups",
    "us", "use", "used", "useful", "usefully", "usefulness", "uses", "using",
    "usually", "v", "value", "various", "'ve", "via", "viz", "vol", "vols",
    "vs", "w", "want", "wants", "wasnt", "way", "wed", "welcome", "went",
    "werent", "whatever", "what'll", "whats", "whence", "whenever",
    "whereafter", "whereas", "whereby", "wherein", "wheres", "whereupon",
    "wherever", "whether", "whim", "whither", "whod", "whoever", "whole",
    "who'll", "whomever", "whos", "whose", "widely", "willing", "wish",
    "within", "without", "wont", "words", "world", "wouldnt", "www", "x", "yes",
    "yet", "youd", "youre", "z", "zero", "a's", "ain't", "allow", "allows",
    "apart", "appear", "appreciate", "appropriate", "associated", "best",
    "better", "c'mon", "c's", "cant", "changes", "clearly", "concerning",
    "consequently", "consider", "considering", "corresponding", "course",
    "currently", "definitely", "described", "despite", "entirely", "exactly",
    "example", "going", "greetings", "hello", "help", "hopefully", "ignored",
    "inasmuch", "indicate", "indicated", "indicates", "inner", "insofar",
    "it'd", "keep", "keeps", "novel", "presumably", "reasonably", "second",
    "secondly", "sensible", "serious", "seriously", "sure", "t's", "third",
    "thorough", "thoroughly", "three", "well", "wonder", "a", "about", "above",
    "above", "across", "after", "afterwards", "again", "against", "all",
    "almost", "alone", "along", "already", "also", "although", "always", "am",
    "among", "amongst", "amoungst", "amount", "an", "and", "another", "any",
    "anyhow", "anyone", "anything", "anyway", "anywhere", "are", "around", "as",
    "at", "back", "be", "became", "because", "become", "becomes", "becoming",
    "been", "before", "beforehand", "behind", "being", "below", "beside",
    "besides", "between", "beyond", "bill", "both", "bottom", "but", "by",
    "call", "can", "cannot", "cant", "co", "con", "could", "couldnt", "cry",
    "de", "describe", "detail", "do", "done", "down", "due", "during", "each",
    "eg", "eight", "either", "eleven", "else", "elsewhere", "empty", "enough",
    "etc", "even", "ever", "every", "everyone", "everything", "everywhere",
    "except", "few", "fifteen", "fify", "fill", "find", "fire", "first", "five",
    "for", "former", "formerly", "forty", "found", "four", "from", "front",
    "full", "further", "get", "give", "go", "had", "has", "hasnt", "have", "he",
    "hence", "her", "here", "hereafter", "hereby", "herein", "hereupon", "hers",
    "herself", "him", "himself", "his", "how", "however", "hundred", "ie", "if",
    "in", "inc", "indeed", "interest", "into", "is", "it", "its", "itself",
    "keep", "last", "latter", "latterly", "least", "less", "ltd", "made",
    "many", "may", "me", "meanwhile", "might", "mill", "mine", "more",
    "moreover", "most", "mostly", "move", "much", "must", "my", "myself",
    "name", "namely", "neither", "never", "nevertheless", "next", "nine", "no",
    "nobody", "none", "noone", "nor", "not", "nothing", "now", "nowhere", "of",
    "off", "often", "on", "once", "one", "only", "onto", "or", "other",
    "others", "otherwise", "our", "ours", "ourselves", "out", "over", "own",
    "part", "per", "perhaps", "please", "put", "rather", "re", "same", "see",
    "seem", "seemed", "seeming", "seems", "serious", "several", "she", "should",
    "show", "side", "since", "sincere", "six", "sixty", "so", "some", "somehow",
    "someone", "something", "sometime", "sometimes", "somewhere", "still",
    "such", "system", "take", "ten", "than", "that", "the", "their", "them",
    "themselves", "then", "thence", "there", "thereafter", "thereby",
    "therefore", "therein", "thereupon", "these", "they", "thickv", "thin",
    "third", "this", "those", "though", "three", "through", "throughout",
    "thru", "thus", "to", "together", "too", "top", "toward", "towards",
    "twelve", "twenty", "two", "un", "under", "until", "up", "upon", "us",
    "very", "via", "was", "we", "well", "were", "what", "whatever", "when",
    "whence", "whenever", "where", "whereafter", "whereas", "whereby",
    "wherein", "whereupon", "wherever", "whether", "which", "while", "whither",
    "who", "whoever", "whole", "whom", "whose", "why", "will", "with", "within",
    "without", "would", "yet", "you", "your", "yours", "yourself", "yourselves",
    "the", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
    "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C",
    "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
    "S", "T", "U", "V", "W", "X", "Y", "Z", "co", "op", "research-articl",
    "pagecount", "cit", "ibid", "les", "le", "au", "que", "est", "pas", "vol",
    "el", "los", "pp", "u201d", "well-b", "http", "volumtype", "par", "0o",
    "0s", "3a", "3b", "3d", "6b", "6o", "a1", "a2", "a3", "a4", "ab", "ac",
    "ad", "ae", "af", "ag", "aj", "al", "an", "ao", "ap", "ar", "av", "aw",
    "ax", "ay", "az", "b1", "b2", "b3", "ba", "bc", "bd", "be", "bi", "bj",
    "bk", "bl", "bn", "bp", "br", "bs", "bt", "bu", "bx", "c1", "c2", "c3",
    "cc", "cd", "ce", "cf", "cg", "ch", "ci", "cj", "cl", "cm", "cn", "cp",
    "cq", "cr", "cs", "ct", "cu", "cv", "cx", "cy", "cz", "d2", "da", "dc",
    "dd", "de", "df", "di", "dj", "dk", "dl", "do", "dp", "dr", "ds", "dt",
    "du", "dx", "dy", "e2", "e3", "ea", "ec", "ed", "ee", "ef", "ei", "ej",
    "el", "em", "en", "eo", "ep", "eq", "er", "es", "et", "eu", "ev", "ex",
    "ey", "f2", "fa", "fc", "ff", "fi", "fj", "fl", "fn", "fo", "fr", "fs",
    "ft", "fu", "fy", "ga", "ge", "gi", "gj", "gl", "go", "gr", "gs", "gy",
    "h2", "h3", "hh", "hi", "hj", "ho", "hr", "hs", "hu", "hy", "i", "i2", "i3",
    "i4", "i6", "i7", "i8", "ia", "ib", "ic", "ie", "ig", "ih", "ii", "ij",
    "il", "in", "io", "ip", "iq", "ir", "iv", "ix", "iy", "iz", "jj", "jr",
    "js", "jt", "ju", "ke", "kg", "kj", "km", "ko", "l2", "la", "lb", "lc",
    "lf", "lj", "ln", "lo", "lr", "ls", "lt", "m2", "ml", "mn", "mo", "ms",
    "mt", "mu", "n2", "nc", "nd", "ne", "ng", "ni", "nj", "nl", "nn", "nr",
    "ns", "nt", "ny", "oa", "ob", "oc", "od", "of", "og", "oi", "oj", "ol",
    "om", "on", "oo", "oq", "or", "os", "ot", "ou", "ow", "ox", "oz", "p1",
    "p2", "p3", "pc", "pd", "pe", "pf", "ph", "pi", "pj", "pk", "pl", "pm",
    "pn", "po", "pq", "pr", "ps", "pt", "pu", "py", "qj", "qu", "r2", "ra",
    "rc", "rd", "rf", "rh", "ri", "rj", "rl", "rm", "rn", "ro", "rq", "rr",
    "rs", "rt", "ru", "rv", "ry", "s2", "sa", "sc", "sd", "se", "sf", "si",
    "sj", "sl", "sm", "sn", "sp", "sq", "sr", "ss", "st", "sy", "sz", "t1",
    "t2", "t3", "tb", "tc", "td", "te", "tf", "th", "ti", "tj", "tl", "tm",
    "tn", "tp", "tq", "tr", "ts", "tt", "tv", "tx", "ue", "ui", "uj", "uk",
    "um", "un", "uo", "ur", "ut", "va", "wa", "vd", "wi", "vj", "vo", "wo",
    "vq", "vt", "vu", "x1", "x2", "x3", "xf", "xi", "xj", "xk", "xl", "xn",
    "xo", "xs", "xt", "xv", "xx", "y2", "yj", "yl", "yr", "ys", "yt", "zi", "zz"
]

# Reference : https://gist.github.com/slowkow/7a7f61f495e3dbb7e3d767f97bd7304b
def remove_emoji(text):
    emoji_pattern = re.compile(
        "["
        u"\U0001F600-\U0001F64F"  # emoticons
        u"\U0001F300-\U0001F5FF"  # symbols & pictographs
        u"\U0001F680-\U0001F6FF"  # transport & map symbols
        u"\U0001F1E0-\U0001F1FF"  # flags (iOS)
        u"\U00002702-\U000027B0"
        u"\U000024C2-\U0001F251"
        "]+",
        flags=re.UNICODE)
    return emoji_pattern.sub(r'', text)

# from: https://www.kaggle.com/shahules/basic-eda-cleaning-and-glove
# maybe a bug, it removes question marks?
spell = SpellChecker()

def correct_spellings(text):
    corrected_text = []
    misspelled_words = spell.unknown(text.split())
    for word in text.split():
        if word in misspelled_words:
            corrected_text.append(spell.correction(word))
        else:
            corrected_text.append(word)
    return " ".join(corrected_text)

def remove_urls(text):
    text = clean(r"http\S+", text)
    text = clean(r"www\S+", text)
    text = clean(r"pic.twitter.com\S+", text)

    return text

def clean(reg_exp, text):
    text = re.sub(reg_exp, " ", text)

    # replace multiple spaces with one.
    text = re.sub('\s{2,}', ' ', text)

    return text

lemmatizer = WordNetLemmatizer()

def clean_all(t, correct_spelling=False, remove_stopwords=False, lemmatize=False):

    # first do bulk cleanup on tokens that don't depend on word tokenization

    # remove xml tags
    t = clean(r"<[^>]+>", t)
    t = clean(r"<", t)
    t = clean(r">", t)

    # remove URLs
    t = remove_urls(t)

    # https://stackoverflow.com/a/35041925
    # replace multiple punctuation with single. Ex: !?!?!? would become ?
    t = clean(r'[\?\.\!]+(?=[\?\.\!])', t)

    t = remove_emoji(t)

    # expand common contractions like "I'm" "he'll"
    t = decontracted(t)

    # now remove/expand bad patterns per word
    words = word_tokenize(t)

    # remove stopwords
    if remove_stopwords is True:
        words = [w for w in words if not w in stopwords]

    clean_words = []

    for w in words:
        # normalize punctuation
        w = re.sub(r'&', 'and', w)

        # expand slang like OMG = Oh my God
        w = unslang(w)

        if lemmatize is True:
            w = lemmatizer.lemmatize(w)

        clean_words.append(w)

    # join the words back into a full string
    t = untokenize(clean_words)

    if correct_spelling is True:
        # this resulted in lots of lost punctuation - omitting for now. Also greatly speeds things up
        t = correct_spellings(t)

    # finally, remove any non ascii and special characters that made it through
    t = clean(r"[^A-Za-z0-9\.\'!\?,\$]", t)

    return t

def get_biterm(doc):
    return ' '.join([biterm for biterm in [
        '_'.join(sorted(biterm)) for biterm in combinations(doc.split(), 2) if biterm[0] != biterm[1]
    ]])

def get_clean_df(i, o):
    df = pd.read_csv(i)

    df['url'] = df.progress_apply(lambda x: ' '.join(re.findall(r'https?://[\w/:%#\$&\?\(\)~\.=\+\-]+', x['text'])), axis=1)
    df['hashtag'] = df.progress_apply(lambda x: ' '.join(re.findall(r'(?<=[\s^])#\w+(?=[\s$])', x['text'])), axis=1)
    df['clean'] = df.progress_apply(lambda x: clean_all(x['text'], False, False), axis=1)
    df['biterms'] = df.progress_apply(lambda x: get_biterm(x['clean']), axis=1)
    df.to_csv(o, index=None, sep='\t')

if __name__ == '__main__':
    get_clean_df('./data/train.csv', './file/train_clean.tsv')
    get_clean_df('./data/test_leak.csv', './file/test_clean.tsv')


text:
import sys
import os
import unittest

import numpy as np
import numpy.testing as npt

from oct2py import octave

sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'build', 'debug'))
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'build', 'debug', 'swig'))

import yafft

class Test2PointFFT(unittest.TestCase):

    def setUp(self):
        octave.restart()
        octave.addpath('./octave')
        octave.addpath('./test/octave')
        octave.eval('pkg load signal')  # load signal package

        # Test data
        self.in1 = np.array([1, 0], dtype=np.complex64)
        self.out1 = np.array([1, 1], dtype=np.complex64)

        self.in2 = np.array([0, 1], dtype=np.complex64)
        self.out2 = np.array([1, -1], dtype=np.complex64)

    def tearDown(self):
        octave.exit()

    def test_octave_2point_fft(self):
        res = octave.my_fft(self.in1)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out1)

        res = octave.my_fft(self.in2)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out2)

    def test_dit_2point_fft(self):
        data = self.in1
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out1)

        data = self.in2
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out2)

    def test_dif_2point_fft(self):
        data = self.in1
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out1)

        data = self.in2
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out2)

class Test4PointFFT(unittest.TestCase):

    def setUp(self):
        octave.restart()
        octave.addpath('./octave')
        octave.addpath('./test/octave')
        octave.eval('pkg load signal')  # load signal package

        # Test data
        self.in1 = np.array([1, 0, 0, 0], dtype=np.complex64)
        self.out1 = np.array([1, 1, 1, 1], dtype=np.complex64)

        self.in2 = np.array([0, 1, 0, 0], dtype=np.complex64)
        self.out2 = np.array([1, -1j, -1, 1j], dtype=np.complex64)

        self.in3 = np.array([0, 0, 1, 0], dtype=np.complex64)
        self.out3 = np.array([1, -1, 1, -1], dtype=np.complex64)

        self.in4 = np.array([0, 0, 0, 1], dtype=np.complex64)
        self.out4 = np.array([1, 1j, -1, -1j], dtype=np.complex64)

    def tearDown(self):
        octave.exit()

    def test_octave_4point_fft(self):
        res = octave.my_fft(self.in1)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out1)

        res = octave.my_fft(self.in2)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out2)

        res = octave.my_fft(self.in3)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out3)

        res = octave.my_fft(self.in4)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out4)

    def test_dit_4point_fft(self):
        data = self.in1
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out1)

        data = self.in2
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out2)

        data = self.in3
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out3)

        data = self.in4
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out4)

    def test_dif_4point_fft(self):
        data = self.in1
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out1)

        data = self.in2
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out2)

        data = self.in3
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out3)

        data = self.in4
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out4)

class Test8PointFFT(unittest.TestCase):

    def setUp(self):
        octave.restart()
        octave.addpath('./octave')
        octave.addpath('./test/octave')
        octave.eval('pkg load signal')  # load signal package

        # Test data
        v = 1/np.sqrt(2)

        self.in1 = np.array([1, 0, 0, 0, 0, 0, 0, 0], dtype=np.complex64)
        self.out1 = np.array([1, 1, 1, 1, 1, 1, 1, 1], dtype=np.complex64)

        self.in2 = np.array([0, 1, 0, 0, 0, 0, 0, 0], dtype=np.complex64)
        self.out2 = np.array([1, v-1j*v, -1j, -v-1j*v, -1, -v+1j*v, 1j, v+1j*v], dtype=np.complex64)

        self.in3 = np.array([0, 0, 1, 0, 0, 0, 0, 0], dtype=np.complex64)
        self.out3 = np.array([1, -1j, -1, 1j, 1, -1j, -1, 1j], dtype=np.complex64)

        self.in4 = np.array([0, 0, 0, 1, 0, 0, 0, 0], dtype=np.complex64)
        self.out4 = np.array([1, -v-1j*v, 1j, v-1j*v, -1, v+1j*v, -1j, -v+1j*v], dtype=np.complex64)

        self.in5 = np.array([0, 0, 0, 0, 1, 0, 0, 0], dtype=np.complex64)
        self.out5 = np.array([1, -1, 1, -1, 1, -1, 1, -1], dtype=np.complex64)

        self.in6 = np.array([0, 0, 0, 0, 0, 1, 0, 0], dtype=np.complex64)
        self.out6 = np.array([1, -v+1j*v, -1j, v+1j*v, -1, v-1j*v, 1j, -v-1j*v], dtype=np.complex64)

        self.in7 = np.array([0, 0, 0, 0, 0, 0, 1, 0], dtype=np.complex64)
        self.out7 = np.array([1, 1j, -1, -1j, 1, 1j, -1, -1j], dtype=np.complex64)

        self.in8 = np.array([0, 0, 0, 0, 0, 0, 0, 1], dtype=np.complex64)
        self.out8 = np.array([1, v+1j*v, 1j, -v+1j*v, -1, -v-1j*v, -1j, v-1j*v], dtype=np.complex64)

    def tearDown(self):
        octave.exit()

    def test_octave_8point_fft(self):
        res = octave.my_fft(self.in1)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out1)

        res = octave.my_fft(self.in2)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out2)

        res = octave.my_fft(self.in3)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out3)

        res = octave.my_fft(self.in4)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out4)

        res = octave.my_fft(self.in5)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out5)

        res = octave.my_fft(self.in6)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out6)

        res = octave.my_fft(self.in7)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out7)

        res = octave.my_fft(self.in8)
        res = np.squeeze(res)
        npt.assert_almost_equal(res, self.out8)

    def test_dit_8point_fft(self):
        data = self.in1
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out1)

        data = self.in2
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out2)

        data = self.in3
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out3)

        data = self.in4
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out4)

        data = self.in5
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out5)

        data = self.in6
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out6)

        data = self.in7
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out7)

        data = self.in8
        yafft.fft_radix2(data, yafft.DECIMATION_IN_TIME)
        npt.assert_almost_equal(data, self.out8)

    def test_dif_8point_fft(self):
        data = self.in1
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out1)

        data = self.in2
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out2)

        data = self.in3
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out3)

        data = self.in4
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out4)

        data = self.in5
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out5)

        data = self.in6
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out6)

        data = self.in7
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out7)

        data = self.in8
        yafft.fft_radix2(data, yafft.DECIMATION_IN_FREQUENCY)
        npt.assert_almost_equal(data, self.out8)

if __name__ == '__main__':
    unittest.main()

ext: py

max_stars_repo_name: danbar/YaFFT

max_issues_repo_name: danbar/YaFFT

max_forks_repo_name: danbar/YaFFT

reason: import numpy


text:
'''
绘制直方图
'''
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import mlab

#数据去一维正态分布
mu = 3
sigma =0.1
x= np.random.normal(mu,sigma,1000)
'''
x,  x轴数据
bins=None 整数或数组 条形图个数
range=None,范围
density=None,是否以密度的形式显示
weights=None,
cumulative=False,
bottom=None,
histtype='bar',线条类型 bar":方形，"barstacked":柱形,"step":"未填充线条""stepfilled":"填充线条"
align='mid', 对齐方式 left，mid，right
orientation='vertical', "horizontal":水平，"vertical":垂直
rwidth=None,
log=False,单位是否以科学计术法
color=None,指定条状图的颜色
label=None,
stacked=False,
normed=None,密度,也就是每个条状图的占比例比,默认为1
'''
n ,n_bins,patches=plt.hist(x,100,density=1,facecolor= 'b')

y = mlab.normpdf(n_bins, mu, sigma)
plt.plot(n_bins,y,'r--')
plt.xlabel('x轴',fontproperties = "SimHei")
plt.ylabel('y轴',fontproperties="SimHei")
plt.title(r'正态分布 : $\mu=3$, $\sigma=0.1$',fontproperties="SimHei")
plt.subplots_adjust(left=0.15)
plt.show()

max_stars_repo_name: asglglgl/PythonPILImage

max_issues_repo_name: asglglgl/PythonPILImage

max_forks_repo_name: asglglgl/PythonPILImage


text:
import numpy as np

class ReplayBuffer:
    def __init__(self, memory_size=1000000, seed=None):
        self._memory_size = memory_size
        self.reset()
        self.seed(seed=seed)

    @property
    def memory(self):
        return self._memory

    def seed(self, seed=None):
        self._rng = np.random.default_rng(seed)

    def reset(self):
        self._memory = []
        self._next_idx = 0

    def add(self, experience):
        if self._next_idx >= len(self):
            self._memory.append(experience)
        else:
            self._memory[self._next_idx] = experience
        self._next_idx = (self._next_idx + 1) % self._memory_size

    def sample(self, batch_size):
        return [self._memory[i] for i in
                self._rng.integers(0, len(self), batch_size)]

    def __len__(self):
        return len(self._memory)

    def __repr__(self):
        return f'{type(self).__name__}({len(self):,.0f})'


text:
###############################################################################
#                                                                             #
# file:    .py                                                                #
#                                                                             #
# authors: BitBuckets FRC 4183                                                #
#                                                                             #
# date:    April 1st 2019                                                     #
#                                                                             #
# brief:                                                                      #
#                                                                             #
###############################################################################

###############################################################################
# Imports
###############################################################################
# Execution
import os
import time
# Math
import math
import numpy as np
# Vision
import cv2
# 4183
from configs import configs

###############################################################################
# Functions
###############################################################################
# display_scaled: displayes scaled image
# point_dist: distance between two points
# Point Object
#   object: x,y
#   dist() to other point
#   angle() to other point
# rect: Rectangle
#  [center x, center y],
#  [width, height]
#  Note that the positive vertical axis points down
# RotatedRect Object
#   object:   [center x, center_y
#              width, height
#              rotation, rotation]
#   ratio() of height/width
# VisionTarget
#   object: l_rect, r_rect (left and right rotated rectangle)
# dict returns
#   angle (angle of left rectange center point to right rectange center point)
#   parallax (height of left-right rectangle / left+right rectangle) is related to view prependicular (0) right from normal (neg) or left from normal (pos)
#   distance (distance to target in meters)
#   pos_x, pos_y (center between center of left and right rectangle)
#   size (distance between left and right rect center / camera width)
# Process Images:
#   FindTarget()
#   drawrect()
# livevideo: analyze stream
# singleimage: analyze one image
# Main: for testing
###############################################################################

def display_scaled_image(name, image, scale):
    """Function to display a scaled cv2 image
    :param name:
        Window name
    :type name:
        basestring
    :param image:
        Image as numpy array
    :type image:
        numpy.ndarray
    :param scale:
        Scale factor applied to image
    :type scale:
        float
    """
    height, width = image.shape[:2]
    cv2.imshow(name, cv2.resize(image,
            (int(scale * width), int(scale * height)),
            interpolation=cv2.INTER_CUBIC))

def point_dist(a, b): # distanec between two point objects
    x_1, y_1 = a
    x_2, y_2 = b
    return math.sqrt((x_1 - x_2) ** 2 + (y_1 - y_2) ** 2)

class Point(object):
    def __init__(self, x, y=None):
        """
        Point class, is a point
        :param x: x pos (normally in mm)
        :param y: y pos (normally in mm)
        -- or --
        :param x: (x, y) pos tuple
        """
        if y is None:
            self.x = x[0]
            self.y = x[0]
        else:
            self.x = x
            self.y = y

    def dist(self, point):
        """
        Caculates the distance to the selected point
        :param point: Another point
        :type point: Point
        :return: Distance
        :rtype: float
        """
        return math.sqrt((self.x - point.x)**2 + (self.y - point.y)**2)

    def angle(self, point):
        delta_x = self.x - point.x
        delta_y = self.y - point.y
        return math.atan2(delta_y, delta_x)

class RotatedRect(object):
    # Rectangle :
    # raw_rect: [center x, center y],[width, height]
    # [Center x, y
    #  width, height
    #  rotation, rotation]
    def __init__(self, rect):
        self.raw_rect = rect
        self.center_pos = Point(rect[0][0], rect[0][1])
        self.width = min(rect[1])
        self.height = max(rect[1])
        self.angle = rect[2]

    @property
    def ratio(self):
        """ Returns the ratio, always greater than 1 """
        return self.height / self.width

class VisionTarget(object):
    ############
    # Constants
    ############
    # Data from 4.10 Vision Tragets
    # a pair of 5½ in. (~14 cm) long by 2 in. (~5 cm) wide strips
    rect_height = 5.5
    rect_height_m = rect_height * 0.0254
    rect_width = 2
    rect_aspect_ratio = rect_height / rect_width
    angle = 90 - (2 * 14.5)  # angled toward each other at ~14.5 degrees
    center_cap = 11.31  # cacualted based on specs
    ############
    camera_hfov = configs['fov']            # field of view degrees
    camera_hres = configs['camera_res'][0]  # pixels
    camera_vres = configs['camera_res'][1]  # pixels
    camera_px_per_deg = camera_hres / camera_hfov
    ############

    def __init__(self, left_rect, right_rect):
        self.l_rect = RotatedRect(left_rect)
        self.r_rect = RotatedRect(right_rect)

    @property
    def angle(self):
        """Angle from target 1 to 2"""
        return self.l_rect.center_pos.angle(self.r_rect.center_pos)

    @property
    def parallax(self):
        """
        unitless parallax between the left and right strips,
        returns Nan if we think one of the rectangles is covered
        negative if we are on the right side of the target
        "should" be invariant of the distance to target
        """
        aspect_tol = 0.1

        # Check left rect ratio for left rect covered
        if not (1 - aspect_tol) * self.rect_aspect_ratio < self.l_rect.ratio: return float('NaN')
        # Check right rect ratio for right rect covered
        if not (1 - aspect_tol) * self.rect_aspect_ratio < self.r_rect.ratio: return float('NaN')

        return (1000 * (self.l_rect.height - self.r_rect.height)) / (self.l_rect.height + self.r_rect.height)

    @property
    def distance(self):
        """
        returns an estimated distance to target in meters
        """
        pixel_height = (self.l_rect.height + self.r_rect.height) / 2.0
        angle = pixel_height / self.camera_px_per_deg
        dist_m = self.rect_height_m / math.tan(math.radians(angle))
        return dist_m

    @property
    def pos(self):
        """
        returns the position as a tuple (x, y) from 0 to 1
        the origin is in the top left of the image (like OpenCV)
        """
        pos_pix_x = (self.l_rect.center_pos.x + self.r_rect.center_pos.x) / 2.0
        pos_pix_y = (self.l_rect.center_pos.y + self.r_rect.center_pos.y) / 2.0

        return pos_pix_x / self.camera_hres, pos_pix_y / self.camera_vres

    @property
    def size(self):
        """
        returns the distance between the targets as a fraction of the image width (from 0 to 1)
        """
        return self.l_rect.center_pos.dist(self.r_rect.center_pos) / self.camera_hres

    def dict(self):
        """
        Returns a dict of important features about the vision target
        """
        return {
            'angle': self.angle,
            'parallax': self.parallax,
            'distance': self.distance,
            'pos_x': self.pos[0],
            'pos_y': self.pos[1],
            'size': self.size
        }

class ProcessImage(object):

    colors = [
        (75, 25, 230),
        (25, 225, 255),
        (200, 130, 0),
        (48, 130, 245),
        (240, 240, 70),
        (230, 50, 240),
        (190, 190, 250),
        (128, 128, 0),
        (255, 190, 230),
        (40, 110, 170),
        (200, 250, 255),
        (0, 0, 128),
        (195, 255, 170),
        (128, 0, 0),
        (128, 128, 128),
        (255, 255, 255),
        (75, 180, 60)
    ]

    def __init__(self):
        (self.cv2major, self.cv2minor, _) = cv2.__version__.split(".") # some CV2 functions have changed from version 3 to 4
        self.HSV_Top          = configs['HSV_Top']         # HSV threshold
        self.HSV_Bot          = configs['HSV_Bot']         # HSV threshold
        self.Min_Rect_Area    = configs['Min_Area']        # minimum size of objects to qualify as target
        self.Max_Trgt_Ratio   = configs['MaxTargetRatio']  # maximum ratio between target hight versus distance to target
        self.Color_Factors    = configs['ColorFactors']    # Optimal Color Transformation, obtained from Principal Component Analysis
        self.cf               = np.array([[self.Color_Factors[0],self.Color_Factors[1],self.Color_Factors[2]]],dtype='float32')

        # following paramters might not be applicable each game
        self.Rect_Ratio_Limit = 6       # Max height/width
        self.Min_Ang          = 50      # Min rotation angle of rectangle
        self.Max_Ang          = 75      # Max rotation angle of rectangle

    def FindTarget(self, image):
        height, width, _ = image.shape
        image_area = height * width

        # Convert BGR to HSV 8ms
        HSV_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

        # HSV threshold  7ms
        threshold = cv2.inRange(HSV_image, self.HSV_Top, self.HSV_Bot)

        # Find Contours  100ms
        if self.cv2major == '4':
            contours, _ = cv2.findContours(threshold, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
        else:
            _, contours, _ = cv2.findContours(threshold, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
        # print("proc:{}contours".format(len(contours)))

        # Filter Contours that are smaller than threshold 40ms
        c_contours = list() # candidate objects
        for contour in contours:
            contour_area = cv2.contourArea(contour)
            if contour_area > (self.Min_Rect_Area * image_area):
                c_contours.append(contour)

        # Convert min area rect 80ms
        min_rectangles = [cv2.minAreaRect(contour) for contour in c_contours]

        # Filter Rectangles, and classify as left (leaning right) or right (leaning left) 0,2ms
        right_rect = list()
        left_rect = list()
        for rect in min_rectangles:
            width, height = rect[1]
            rect_area = width * height
            # Filter small (relative to image) rects
            if rect_area / image_area < self.Min_Rect_Area:
                continue

            # Filter things that are too long and skinny
            if max(width, height) / min(width, height) > self.Rect_Ratio_Limit:
                continue

            # Classify if we are looking at a right or left rectangle
            if abs(rect[2]) < 45:
                right_rect.append(rect)
            else:
                left_rect.append(rect)

        rect_pairs = list()

        # Pair rects (based on the left rects) 0.5ms
        for l_rect in left_rect:
            found_match = False
            l_x, l_y = l_rect[0]
            l_width, l_height = l_rect[1]

            for r_index, r_rect in enumerate(right_rect):
                dist = point_dist(l_rect[0], r_rect[0])
                # Get some properties
                r_x, r_y = r_rect[0]
                r_width, r_height = r_rect[1]

                # Check if the left rectangle is right of the current right rectangle (this means it cannot be valid)
                if r_x < l_x:
                    continue

                # Check if the dist between points vs the rectangle height is too large
                if dist / max(l_width, l_height) > self.Max_Trgt_Ratio:
                    continue

                # Check if the angle between the targets is around the right value
                if not (self.Min_Ang < abs(l_rect[2]) - abs(r_rect[2]) < self.Max_Ang):
                    continue

                # If we got this far we found a match!
                found_match = True
                break

            if found_match:
                rect_pairs.append([l_rect, r_rect])
                del right_rect[r_index]

        found_targets = [VisionTarget(t[0], t[1]) for t in rect_pairs]

        return found_targets

    def FindTargetFast(self, image):
        height, width, _ = image.shape
        image_area = height * width

        # Convert BGR to optimized gray scale
        # Color transformation factors were computed with PCA and calibration images
        gray = cv2.transform(imgage,cf)

        # HSV threshold
        ret, thresh = cv.threshold(gray,127,255,cv.THRESH_BINARY)

import numpy as np
import os
import cv2
import time
import math
from configs import configs
folder = 'D:/GitHub/Python Playground/BucketVision/2019 Pipeline'
files = [os.path.join(folder, f) for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f))]
images = [f for f in files if f.endswith(".png")]
img = cv2.imread(images[0])
cv2.imshow('test',img)
cv2.waitKey()

cv2major, cv2minor, _) = cv2.__version__.split(".") # some CV2 functions have changed from version 3 to 4
HSV_Top          = configs['HSV_Top']         # HSV threshold
HSV_Bot          = configs['HSV_Bot']         # HSV threshold
Min_Rect_Area    = configs['Min_Area']        # minimum size of objects to qualify as target
Max_Trgt_Ratio   = configs['MaxTargetRatio']  # maximum ratio between target hight versus distance to target
Color_Factors    = configs['Colorfactors']    # Optimal Color Transformation, obtained from Principal Component Analysis
cf               = np.array([[Color_Factors[0],Color_Factors[1],Color_Factors[2]]],dtype='float32')
Gray_Thresh      = configs['GrayThresh']
# following paramters might not be applicable each game
Rect_Ratio_Limit = 6       # Max height/width
Min_Ang          = 50      # Min rotation angle of rectangle
Max_Ang          = 75      # Max rotation angle of rectangle
image=img
height, width, _ = image.shape
image_area = height * width

# Convert BGR to optimized gray scale
# Color transformation factors were computed with PCA and calibration images
gray = cv2.transform(img,cf)

# Smoothing not needed
#grayblr = cv2.GaussianBlur(gray, (3, 3), 0)

# HSV threshold
ret, thresh = cv2.threshold(gray,Gray_Thresh,255,cv2.THRESH_BINARY)

#edged = cv2.Canny(grayblr, 50, 100)
#edged = cv2.dilate(edged, None, iterations=1)
#edged = cv2.erode(edged, None, iterations=1)

connectivity = 4 # You need to choose 4 or 8 for connectivity type

#output = cv2.connectedComponentsWithStats(thresh, connectivity, cv2.CV_32S)
#print(time.time() -start)
#num_labels = output[0] # The first cell is the number of labels
#labels     = output[1]# The second cell is the label matrix
#stats      = output[2] # The third cell is the stat matrix
#centroids  = output[3] # The fourth cell is the centroid matrix
# Statistics output for each label, including the background label, see below for available statistics. Statistics are accessed via stats[label, COLUMN] where available columns are defined below.
#cv2.CC_STAT_LEFT The leftmost (x) coordinate which is the inclusive start of the bounding box in the horizontal direction.
#cv2.CC_STAT_TOP The topmost (y) coordinate which is the inclusive start of the bounding box in the vertical direction.
#cv2.CC_STAT_WIDTH The horizontal size of the bounding box
#cv2.CC_STAT_HEIGHT The vertical size of the bounding box
#cv2.CC_STAT_AREA The total area (in pixels) of the connected component

num_labels, labels = cv2.connectedComponents(thresh, connectivity = 8, ltype=cv2.CV_16U )

# select one-by-one ALL labelled objects using its label values
for lbl in np.arange(num_labels):
    # select the image part relative to lbl
    objImg    = 1.0*(labels == lbl)
    moments   = cv2.moments(objImg)
    huMoments = cv2.HuMoments(moments)
if (moments['m00'] != 0) :
    area         = moments['m00']
    center_x     = moments['m10'] / moments['m00']
    center_y     = moments['m01'] / moments['m00']
    if not(moments['mu20'] == moments['mu02']):
        angle        = ( math.atan2(2. * moments['mu11'] , (moments['mu20'] - moments['mu02']) ) )/2.
        tmp1 = moments['mu20'] - moments['mu02']
        tmp2 = math.sqrt(4.*moments['mu11']*moments['mu11'] + tmp1*tmp1)
        tmp3 = moments['mu20']+moments['mu02']
        lambda1      = (tmp3 + tmp2) / 2.
        lambda2      = (tmp3 - tmp2) / 2.
        eccentricity = math.sqrt(1. - lambda2/lambda1)
    # huMoments

moments -> angle

#TYPE_5_8
#TYPE_7_12
#TYPE_9_16
fast = cv2.FastFeatureDetector.create(threshold = 24, nonmaxSuppression = True, type = cv2.FastFeatureDetector_TYPE_9_16)
start = time.time()
kp = fast.detect(grayblr,None)
print(time.time() -start)
imgRes=cv2.drawKeypoints(grayblr, kp, outImage=np.array([]), color=(255,0,0))
cv2.imshow('test',imgRes)
cv2.waitKey()

cv2.destroyAllWindows()
img = cv2.imread(images[0])
width = int(img.shape[1] * 50 / 100)
height = int(img.shape[0] * 50 / 100)
dim = (width, height)
img = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
img = img[int(height*(configs['crop_top'])):int(height*(configs['crop_bot'])), :, :]
start = time.time()
kp = fast.detect(img[:,:,1],None) # only on green channel as we have green lights
print(time.time() -start)
imgRes=cv2.drawKeypoints(img[:,:,1], kp, outImage=np.array([]), color=(255,0,0))
cv2.imshow('test',imgRes)
cv2.waitKey()
cv2.destroyAllWindows()

        # Find Contours  100ms
        if self.cv2major == '4':
            contours, _ = cv2.findContours(threshold, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
        else:
            _, contours, _ = cv2.findContours(threshold, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
        # print("proc:{}contours".format(len(contours)))

        # Filter Contours that are smaller than threshold 40ms
        c_contours = list() # candidate objects
        for contour in contours:
            contour_area = cv2.contourArea(contour)
            if contour_area > (self.Min_Rect_Area * image_area):
                c_contours.append(contour)

        # Convert min area rect 80ms
        min_rectangles = [cv2.minAreaRect(contour) for contour in c_contours]

        # Filter Rectangles, and classify as left (leaning right) or right (leaning left) 0,2ms
        right_rect = list()
        left_rect = list()
        for rect in min_rectangles:
            width, height = rect[1]
            rect_area = width * height
            # Filter small (relative to image) rects
            if rect_area / image_area < self.Min_Rect_Area:
                continue

            # Filter things that are too long and skinny
            if max(width, height) / min(width, height) > self.Rect_Ratio_Limit:
                continue

            # Classify if we are looking at a right or left rectangle
            if abs(rect[2]) < 45:
                right_rect.append(rect)
            else:
                left_rect.append(rect)

        rect_pairs = list()

        # Pair rects (based on the left rects) 0.5ms
        for l_rect in left_rect:
            found_match = False
            l_x, l_y = l_rect[0]
            l_width, l_height = l_rect[1]

            for r_index, r_rect in enumerate(right_rect):
                dist = point_dist(l_rect[0], r_rect[0])
                # Get some properties
                r_x, r_y = r_rect[0]
                r_width, r_height = r_rect[1]

                # Check if the left rectangle is right of the current right rectangle (this means it cannot be valid)
                if r_x < l_x:
                    continue

                # Check if the dist between points vs the rectangle height is too large
                if dist / max(l_width, l_height) > self.Max_Trgt_Ratio:
                    continue

                # Check if the angle between the targets is around the right value
                if not (self.Min_Ang < abs(l_rect[2]) - abs(r_rect[2]) < self.Max_Ang):
                    continue

                # If we got this far we found a match!
                found_match = True
                break

            if found_match:
                rect_pairs.append([l_rect, r_rect])
                del right_rect[r_index]

        found_targets = [VisionTarget(t[0], t[1]) for t in rect_pairs]

        return found_targets

    @staticmethod
    def drawtargets(image, targets):
        height, width, _ = image.shape
        for index, target in enumerate(targets):
            found_cont = [np.int0(cv2.boxPoints(r)) for r in [target.l_rect.raw_rect, target.r_rect.raw_rect]]
            try:
                color = ProcessImage.colors[index]
                image = cv2.drawContours(image, found_cont, -1, color, 3)
                x, y = target.pos
                image = cv2.circle(image, (int(x * width), int(y * height)),
                                    int((target.size * width) / 4),
                                    color, -1)
            except IndexError:
                # More targets than colors!
                pass
        return image

def live_video():
    import os
    from configs import configs
    import time
    proc = ProcessImage()

    cam = cv2.VideoCapture(0)
    frame_width = 320
    frame_height = 240
    cam.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
    cam.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)
    if os.name == 'nt':
        cam.set(cv2.CAP_PROP_EXPOSURE, -10)
    else:
        os.system("v4l2-ctl -c exposure_absolute={}".format(10))
    frame_time = list()
    while True:
        start = time.time()
        if len(frame_time) == 10:
            print("FPS:{}".format(1/sum(frame_time)))
            frame_time = list()
        ret_val, img = cam.read()
        camera_res = img.shape
        img = img[int(camera_res[1]*(configs['crop_top'])):int(camera_res[1]*(configs['crop_bot'])), :, :]
        res = proc.FindTarget(img)
        display_scaled_image('test', proc.drawtargets(img, res), 1)
        if cv2.waitKey(1) == 27:
            break  # esc to quit
        frame_time.append(time.time() - start)
    cam.release()
    cv2.destroyAllWindows()

def single_image(image_path):
    proc = ProcessImage()
    img = cv2.imread(image_path)
    found_targets = proc.FindTarget(img)
    img = proc.drawtargets(img, found_targets)
    if len(found_targets) > 0:
        pass
        # print(found_targets[-1].l_rect.raw_rect)
    display_scaled_image('test', img, 0.5)

if __name__ == '__main__':
    # live_video()
    # exit()
    folder = 'D:/GitHub/Python Playground/BucketVision/2019 Pipeline'
    files = [os.path.join(folder, f) for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f))]
    images = [f for f in files if f.endswith(".png")]
    for image in images:
        # print(image)
        single_image(image)
        cv2.waitKey(20)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

max_stars_repo_path: 2019 Pipeline - mp/processimage.py

max_stars_repo_name: uutzinger/BucketVision

max_issues_repo_path: 2019 Pipeline - mp/processimage.py

max_issues_repo_name: uutzinger/BucketVision

max_forks_repo_path: 2019 Pipeline - mp/processimage.py

max_forks_repo_name: uutzinger/BucketVision


text:
from __future__ import division

import wx
import os

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure
from matplotlib import ticker as mticker
from matplotlib import transforms as mtransforms
import numpy as n
from time import sleep, time
import threading
from collections import deque
from .util import get_next_filename

class ScrollingLocator(mticker.MaxNLocator):

    def view_limits(self, vmin, vmax):
        """ Leave unchanged, for smooth scrolling """
        return mtransforms.nonsingular(vmin, vmax)

def silly_gen(inc=0.1):
    """
    a silly generator function producing 'data'
    (really just a sine wave plus noise)
    """
    pt = 0.
    while True:
        sleep(0.1)
        rl = n.sin(2 * n.pi * pt) + n.sin(2 * n.pi * pt / 50.)
        rl += 0.1* n.random.randn()
        yield pt, rl
        pt += inc

# threading code mostly stolen from http://wiki.wxpython.org/LongRunningTasks

# Define notification events
import wx.lib.newevent

# for new data available
ResultEvent, EVT_RESULT = wx.lib.newevent.NewEvent()

# for scan being finished
FinishedEvent, EVT_FINISHED = wx.lib.newevent.NewEvent()

# Thread class that executes processing
class WorkerThread(threading.Thread):
    """Worker Thread Class."""
    def __init__(self, notify_window, gen):
        """Init Worker Thread Class."""
        threading.Thread.__init__(self)
        self.gen = gen
        self._notify_window = notify_window
        self._want_abort = 0

    def run(self):
        """Run Worker Thread."""
        # This is the code executing in the new thread.
        start = time()
        # peek at the abort variable once in a while to see if we should stop
        for data in self.gen:
            if self._want_abort:
                break
            # Send data to the parent thread
            wx.PostEvent(self._notify_window, ResultEvent(data=data))
        # Signal that we are all done
        elapsed = time() - start
        wx.PostEvent(self._notify_window, FinishedEvent(elapsed=elapsed))

    def abort(self):
        """abort worker thread."""
        # Method for use by main thread to signal an abort
        self._want_abort = 1

class MonitorWindow(wx.Frame):

    def __init__(self, parent, title, datagen=None):
        wx.Frame.__init__(self, parent, title=title, size=(500,400))

        if datagen is None:
            datagen = silly_gen()

        self.statusbar = self.CreateStatusBar()
        self.panel = MonitorPanel(self, datagen)
        self.save_to_dir = os.path.expanduser('~')

        filemenu = wx.Menu()
        menuExit = filemenu.Append(wx.ID_EXIT, "E&xit", " Stop program")
        menuSave = filemenu.Append(wx.ID_SAVE, "&Save", " Save a file")

        menuBar = wx.MenuBar()
        menuBar.Append(filemenu, "&File")
        self.SetMenuBar(menuBar)

        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
        self.Bind(wx.EVT_MENU, self.OnSave, menuSave)

        # shortcuts
        shortcuts = wx.AcceleratorTable([
            (wx.ACCEL_CTRL, ord('S'), wx.ID_SAVE),
            ])
        self.SetAcceleratorTable(shortcuts)

    def OnExit(self, e):
        # Runs when the 'Exit' menu option is selected,
        # but not when the x is hit
        self.Close(True)

    def OnSave(self, e):
        xy = self.panel.get_data()
        dlg = wx.FileDialog(self,
                message="Save NPY file",
                defaultDir=self.save_to_dir,
                defaultFile=get_next_filename(self.save_to_dir,
                                              fmt="monitor%03d.npy"),
                wildcard="NPY files (*.npy)|*.npy",
                style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            self.save_to_dir = dlg.GetDirectory()
            path = dlg.GetPath()
            n.save(path, xy)
            self.statusbar.SetStatusText('Saved %s' % path)

class MonitorPanel(wx.Panel):
    """
    Panel encompassing a line monitor graph.

    Pulls x,y data from the provided generator `datagen`
    and plots a live 2D graph.

    """

    def __init__(self, parent, datagen):

        wx.Panel.__init__(self, parent)

        self.datagen = datagen

        fig = Figure()
        self.ax = fig.add_subplot(111)

        self.ax.xaxis.set_major_locator(ScrollingLocator())

        # maintain x and y lists (we'll append to these as we go)
        self.setup_deques([], [])

        self.line, = self.ax.plot(self.x, self.y)

        self.canvas = FigureCanvasWxAgg(self, -1, fig)
        self.canvas.draw()

        self.checkbox = wx.CheckBox(self, label="Limit to")
        self.Bind(wx.EVT_CHECKBOX, self.impose_limit)
        self.spinbox = wx.SpinCtrlDouble(self,
                value='100', min=10, max=10000, inc=10)
        self.Bind(wx.EVT_SPINCTRLDOUBLE, self.impose_limit)
        self.clear_button = wx.Button(self, label="Clear")
        self.clear_button.Bind(wx.EVT_BUTTON, self.on_clear_button)
        self.start_button = wx.Button(self, label="Start")
        self.start_button.Bind(wx.EVT_BUTTON, self.on_start_button)

        self.subsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.subsizer.Add(self.checkbox, 0, wx.EXPAND)
        self.subsizer.Add(self.spinbox, 1, wx.EXPAND)
        self.subsizer.Add(wx.StaticText(self, label='data points'),
                0, wx.ALIGN_CENTER)
        self.subsizer.Add(self.clear_button, 0, wx.EXPAND)
        self.subsizer.Add(self.start_button, 0, wx.EXPAND)

        self.box = wx.StaticBox(self, label="Monitor")
        self.sizer = wx.StaticBoxSizer(self.box, orient=wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.EXPAND)
        self.sizer.AddSpacer(5)
        self.sizer.Add(self.subsizer, 0, wx.EXPAND)

        self.SetSizer(self.sizer)
        self.SetAutoLayout(1)
        self.sizer.Fit(self)

        self.running = False
        self.Bind(EVT_RESULT, self.on_result)

    def on_start_button(self, event):
        if not self.running:
            self.start_worker()
            self.running = True
            self.start_button.SetLabel('Stop')
        else:
            self.abort_worker()
            self.running = False
            self.start_button.SetLabel('Resume')

    def on_clear_button(self, event):
        self.x.clear()
        self.y.clear()

    def __del__(self):
        # this doesn't seem to work
        self.abort_worker()

    def abort_worker(self):
        # tell worker to finish
        self.worker.abort()
        self.worker.join()

    def setup_deques(self, x, y, maxlen=None):
        self.x = deque(x, maxlen)
        self.y = deque(y, maxlen)

    def start_worker(self):
        self.worker = WorkerThread(self, self.datagen)
        self.worker.start()

    def on_result(self, event):
        if event.data is None:
            pass
        else:
            x,y = event.data

            self.x.append(x)
            self.y.append(y)

            self.line.set_data(self.x, self.y)
            self.ax.relim()
            self.ax.autoscale_view()
            self.canvas.draw()

    def impose_limit(self, event):
        if self.checkbox.IsChecked():
            maxlen = self.spinbox.GetValue()
        else:
            maxlen = None
        self.setup_deques(self.x, self.y, maxlen=maxlen)

    def get_data(self):
        return self.line.get_data()

if __name__ == "__main__":
    title = 'Monitor'

    from .config import load_config
    cfg = load_config()
    pulsechan = cfg.get('counting', 'pulsechan')
    countchan = cfg.get('counting', 'countchan')

    import sys
    fake = ('--fake' in sys.argv)

    try:
        import PyDAQmx as daq
    except NotImplementedError:
        fake = True

    if fake:
        gen = silly_gen()
        title += ' (fake)'
    elif '--gated' in sys.argv:
        from .expt import gen_gated_counts
        gen = gen_gated_counts(t=0.1)
        title += ' (gated)'
    else:
        from .expt import gen_count_rate
        gen = gen_count_rate(t=0.1, pulsechan=pulsechan, countchan=countchan)

    app = wx.App(False)
    frame = MonitorWindow(None, title, datagen=gen)
    frame.Show(True)
    app.MainLoop()

max_stars_repo_name: baldwint/circa

max_issues_repo_name: baldwint/circa

max_forks_repo_name: baldwint/circa


text:
import types
import numpy as np

from pwtools.crys import Structure, Trajectory
from pwtools import crys, constants
from pwtools.test.tools import aaae, assert_all_types_equal
from pwtools.test import tools
from pwtools.test.utils.rand_container import get_rand_struct
rand = np.random.rand

# We assume all lengths in Angstrom. Only importans for ASE comparison.

def test_struct():
    natoms = 10
    cell = np.array([[3,0,0],
                     [1.1,5,-0.04],
                     [-0.33,1.5,7]])
    cryst_const = crys.cell2cc(cell)
    coords_frac = rand(natoms,3)
    coords = crys.coord_trans(coords=coords_frac,
                              old=cell,
                              new=np.identity(3))
    symbols = ['H']*natoms
    stress = rand(3,3)
    forces = rand(natoms,3)

    # Use ``cell`` instead of ``cryst_const` as input such that
    # atoms.get_cell() test passes (see below for why -- cell orientation)
    st = Structure(coords_frac=coords_frac,
                   symbols=symbols,
                   cell=cell,
                   stress=stress,
                   forces=forces,
                   etot=42)

    # Test if all getters work.
    for name in st.attr_lst:
        print(name)
        st.try_set_attr(name)
        assert getattr(st, name) is not None, "attr None: %s" %name
        assert eval('st.get_%s()'%name) is not None, "getter returns None: %s" %name
    aaae(coords_frac, st.coords_frac)
    aaae(cryst_const, st.cryst_const)
    aaae(coords, st.coords)
    assert st.natoms == natoms

    st = Structure(coords_frac=coords_frac,
                   symbols=symbols,
                   cell=cell)
    aaae(coords, st.get_coords())

    # Cell calculated from cryst_const has defined orientation in space which may be
    # different from the original `cell`, but the volume and underlying cryst_const
    # must be the same.
    st = Structure(coords_frac=coords_frac,
                   symbols=symbols,
                   cryst_const=cryst_const)
    assert st.get_cell() is not None
    np.testing.assert_almost_equal(crys.volume_cell(cell),
                                   crys.volume_cell(st.get_cell()))
    aaae(cryst_const, crys.cell2cc(st.get_cell()))

    # units
    st = Structure(coords_frac=coords_frac,
                    cell=cell,
                    symbols=symbols,
                    stress=stress,
                    forces=forces,
                    units={'length': 2, 'forces': 3, 'stress': 4})
    aaae(2*coords, st.coords)
    aaae(3*forces, st.forces)
    aaae(4*stress, st.stress)

    traj = crys.struct2traj(st)
    assert traj.is_traj

    # copy(): Assert everything has another memory location = is a new copy of
    # the object. IntTypes are NOT copied by copy.deepcopy(), which we use in
    # Structure.copy(), apparently b/c they are always automatically copied
    # before in-place operations. Same for float type.
    #
    # >>> a=10; b=a; print(id(a)); print(id(b))
    # 36669152
    # 36669152
    # >>> a*=100; print(id(a)); print(id(b))
    # 72538264
    # 36669152
    # >>> a
    # 100
    # >>> b
    # 10
    #
    # >>> a=[1,2,3]; b=a; print(id(a)); print(id(b))
    # 72624320
    # 72624320
    # >>> a[0] = 44; print(id(a)); print(id(b))
    # 72624320
    # 72624320
    # >>> a
    # [44, 2, 3]
    # >>> b
    # [44, 2, 3]
    st2 = st.copy()
    for name in st.attr_lst:
        val = getattr(st,name)
        if val is not None and not (isinstance(val, int) or \
            isinstance(val, float)):
            val2 = getattr(st2,name)
            assert id(val2) != id(val)
            assert_all_types_equal(val2, val)

def test_get_traj():
    st = Structure(coords_frac=rand(20,3),
                   symbols=['H']*20,
                   forces=rand(20,3),
                   stress=rand(3,3),
                   etot=42.23)
    nstep = 5
    tr = st.get_traj(nstep)
    for name in st.attr_lst:
        print(name)
        attr = getattr(tr, name)
        if attr is not None:
            if name in tr.attrs_nstep:
                assert attr.shape[tr.timeaxis] == nstep
            else:
                attr_st = getattr(st, name)
                assert_all_types_equal(attr, attr_st)

def test_coord_trans():
    natoms = 10
    cell = np.array([[3,0,0],
                     [1.1,5,-0.04],
                     [-0.33,1.5,7]])
    cryst_const = crys.cell2cc(cell)
    coords_frac = rand(natoms,3)
    coords = crys.coord_trans(coords=coords_frac,
                              old=cell,
                              new=np.identity(3))

    st = crys.Structure(coords=coords,
                        cell=cell)
    assert np.allclose(coords_frac, st.coords_frac)
    st = crys.Structure(coords_frac=coords_frac,
                        cell=cell)
    assert np.allclose(coords, st.coords)

    st = crys.Structure(coords=coords,
                        cell=cell)
    assert np.allclose(cryst_const, st.cryst_const)

def test_get_fake_ase_atoms():
    st = get_rand_struct()
    atoms = st.get_fake_ase_atoms()
    assert (st.coords_frac == atoms.get_scaled_positions()).all()
    assert (st.cell == atoms.get_cell()).all()
    assert (atoms.get_atomic_numbers() == np.array(st.get_znucl())).all()

def test_znucl():
    st = Structure(symbols=['Al']*2 + ['N']*3)
    assert st.znucl == [13]*2 + [7]*3
    assert st.znucl_unique == [13,7]

def test_mix():
    symbols = ['H']*3 + ['Au']*7
    natoms = len(symbols)
    st1nf = Structure(coords_frac=rand(natoms,3),
                    symbols=symbols,
                    cell=rand(3,3))
    st2nf = Structure(coords_frac=rand(natoms,3),
                    symbols=symbols,
                    cell=rand(3,3))
    st1f = Structure(coords_frac=rand(natoms,3),
                    symbols=symbols,
                    cell=rand(3,3),
                    forces=rand(natoms,3))
    st2f = Structure(coords_frac=rand(natoms,3),
                    symbols=symbols,
                    cell=rand(3,3),
                    forces=rand(natoms,3))
    for st1,st2 in [(st1f, st2f), (st1nf, st2nf)]:
        tr = crys.mix(st1, st2, alpha=np.linspace(0,1,20))
        assert tr.nstep == 20
        assert tr.coords_frac.shape == (20, st1.natoms, 3)

        for idx,st in [(0,st1), (-1, st2)]:
            tools.assert_dict_with_all_types_almost_equal(st.__dict__,
                                                          tr[idx].__dict__,
                                                          keys=st1.attr_lst)
        for x in [0.5, 0.9]:
            tr = crys.mix(st1, st2, alpha=np.array([x]))
            assert tr.nstep == 1
            tools.assert_all_types_almost_equal(tr[0].coords, (1-x)*st1.coords + x*st2.coords)
            tools.assert_all_types_almost_equal(tr[0].cell, (1-x)*st1.cell + x*st2.cell)
            if tr.forces is not None:
                tools.assert_all_types_almost_equal(tr[0].forces, (1-x)*st1.forces + x*st2.forces)

max_stars_repo_name: elcorto/pwtools

max_issues_repo_name: elcorto/pwtools

max_forks_repo_name: elcorto/pwtools


text:
import streamlit as st;
import pandas as pd;
import numpy as np;
import altair as alt;
import pydeck as pdk;
import matplotlib.pyplot as plt;
import plotly.graph_objects as go;
import plotly.express as px;

import pymysql;

import datetime as dt;
#@st.cache(persist = True)

st.title("United States Accident Data")

st.write(
    'The dataset used for this dashboard is United States data that can be found on kaggle. The intended user for this dashboard are researchers and individuals who are interested in learning more about US accident trends. For this demo, data was subsetted from the full dataset by Kaggle to ensure data can be returned quickly from the database!'
)

st.markdown(
    "###### The full US accidents data set can be found here: https://www.kaggle.com/sobhanmoosavi/us-accidents"
)
st.markdown('
',unsafe_allow_html=True)

@st.cache(persist = True,
allow_output_mutation=True)
def query_data(localhostname,user,pw,db,port,table,nrow=0):
    conn = pymysql.connect(localhostname,user,pw,db,port)
    cursor = conn.cursor()

    #accidents data
    cursor.execute(f'SELECT * FROM {table} LIMIT {nrow}')
    desc = cursor.description
    data = cursor.fetchall()

    data_names = []
    for i in range(len(desc)):
        data_names.append(desc[i][0])

    data_df = pd.DataFrame(data, columns = data_names)
    conn.close()
    return data_df

######### QUERYING DATA A###############
st.header("Part 1")
nrow_acc = st.sidebar.slider("PT1: How much data would you like to query? (100-100000)",100,100000,100, step=100)

st.write(
    'In the sidebar, please choose the amount of data you would like to visualize! You can toggle the view of the raw data by checking and unchecking the box below. Once you query the database, the charts will automatically update with the new data!')
st.markdown("###### Since we are using a subset of the total dataset, the visualizations are not a full representation of the data.")

acc_df= query_data(localhostname='localhost',
             user='root',
             pw='root',
             db='accidents2',
             port=8889,
             table='Accidents',
             nrow=nrow_acc)
acc_df['start_time']=acc_df['start_time'].dt.normalize()
acc_df['end_time']=acc_df['end_time'].dt.normalize()
acc_df['weather_timestamp']=acc_df['weather_timestamp'].dt.normalize()
acc_df['year'] = pd.DatetimeIndex(acc_df['start_time']).year
acc_df['month'] = pd.DatetimeIndex(acc_df['start_time']).month
c_box = st.checkbox("View Raw Data")
if c_box == True:
    s_acc_df = st.dataframe(acc_df)
    'accidents_df', s_acc_df

######### CREATING SEVERITY BARCHART A###############
severity_bar = acc_df.groupby('severity').count()
severity_bar = severity_bar.reset_index()
severity_bar['severity'] = severity_bar['severity'].astype('category')

sev_fig = px.bar(severity_bar, x="severity", y="id")
sev_fig.update_layout(title='Count of accidents by severity',
                  xaxis_type='category',
                   xaxis_title='Severity Score',
                   yaxis_title='Count')
st.plotly_chart(sev_fig, use_container_width=True)

st.write("Most of the crashes from the dataset have a severity score of 2.")

######### CREATING DAY-NIGHT BARCHART A###############
day_night = pd.DataFrame(acc_df['sunrise_sunset'].value_counts()).reset_index()

df_fig = px.bar(day_night, x="index", y="sunrise_sunset")
df_fig.update_layout(title='Count of accidents by Time of Day',
                  xaxis_type='category',
                   xaxis_title='Time of day',
                   yaxis_title='Count')
st.plotly_chart(df_fig, use_container_width=True)

st.write("As expected many accidents occur during the day. Why is that?")

######### CREATING LINE CHART A###############
d_month_count = acc_df.groupby('month').count()
d_month_count = d_month_count.reset_index()
tseries_fig = px.line(d_month_count, x="month", y="id")
tseries_fig.update_layout(title='Number of Accidents per Month',
                   xaxis_title='Month',
                   yaxis_title='Count')
st.plotly_chart(tseries_fig, use_container_width=True)

st.write("A simple timeseries chart of the crashes per month!")

st.markdown('
',unsafe_allow_html=True)

st.header('Part 2')
st.subheader("Let us look at the data on an aggregated level")
st.write("In the sidebar, please input a numeric value to query from the database.")
nrow_ALZ = st.sidebar.number_input("P2: Please input the amount of data you would like to query. (Max:1000000)",500,1000000,500,step=500, key= "ALZ")

ALZ = query_data(localhostname='localhost',
             user='root',
             pw='root',
             db='accidents2',
             port=8889,
             table='accidents_loc_zip',
             nrow=nrow_ALZ)

ALZ['weather_timestamp']=ALZ['weather_timestamp'].dt.normalize()

ALZ_c_box = st.checkbox("View Raw Data",key="env_c_box")
if ALZ_c_box == True:
    s_ALZ = st.dataframe(ALZ)
    'Raw Environment Data', s_ALZ

ALZ['temperature']= ALZ['temperature'].astype(float)
ALZ['humidity']= ALZ['humidity'].astype(float)
ALZ['pressure']= ALZ['pressure'].astype(float)
ALZ['visibility']= ALZ['visibility'].astype(float)
ALZ['wind_speed']= ALZ['wind_speed'].astype(float)

fcs = st.sidebar.radio("PT2: How would you like to group the data?",
        ('city','state','airport_code','timezone','weather_condition'),key='filter_cs')

atype = st.sidebar.radio("PT2: How would you like the data to be aggregated?",
                ("min","max","mean"),key='agg_type')

ftype = st.sidebar.radio("PT2: What type of environmental data would you like to visualize?",
                ("temperature","humidity","pressure","visibility","wind_speed"),key='feat_type')

######### AGGREGATIONS FOR VISUALIZATIONS###############
def filter_plot(cs=fcs,agg=atype,feat=ftype):

    ALZ['temperature']= ALZ['temperature'].astype(float)
    ALZ['humidity']= ALZ['humidity'].astype(float)
    ALZ['pressure']= ALZ['pressure'].astype(float)
    ALZ['visibility']= ALZ['visibility'].astype(float)
    ALZ['wind_speed']= ALZ['wind_speed'].astype(float)
    df = ALZ.groupby(f'{cs}').agg(f'{agg}')
    df=df.reset_index()
    df_fig = px.bar(df, x=f"{cs}", y=f"{feat}")
    df_fig.update_layout(title=f'{agg} {feat} by {cs}',
                   xaxis_title=f'{cs}',
                   yaxis_title=f'{agg} {feat}')
    return st.plotly_chart(df_fig, use_container_width=True)

filter_plot(fcs,atype,ftype)
st.markdown('
',unsafe_allow_html=True)

st.header('Part 3.1')
st.write("Let us see how the data looks visually on a map! The data points are located in CA and OH. Feel free to interact with the map by zooming and panning! Hoever over points to get more information")
midpoint = (ALZ['start_lat'].mean(), ALZ['start_lng'].mean())
cols = ['start_lat','start_lng','city','state','temperature','humidity','pressure','visibility','weather_condition','severity','sunrise_sunset','wind_speed']
ALZ_map = ALZ[cols]

col_group = st.sidebar.radio("PT3.1: What group type would you like to color the points by?",
                ("weather_condition","severity","sunrise_sunset","wind_speed"),key='col_group')

def scat_plotly(col_group = col_group):
    fig = px.scatter_mapbox(ALZ_map, lat="start_lat", lon="start_lng",
                        hover_name="city",
                        hover_data=["city", "state","temperature","humidity","pressure","visibility","weather_condition"],
                        color = f'{col_group}',
                        color_discrete_sequence=px.colors.sequential.thermal, zoom=3, height=300)
    fig.update_layout(mapbox_style="open-street-map")
    fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
    return st.plotly_chart(fig, use_container_width=True)

scat_plotly(col_group)

st.header('Part 3.2')
den_group = st.sidebar.radio("PT3.2: What group type would you like to color the points by?",
                ("temperature","humidity","pressure","visibility","wind_speed"),key='den_group')
def den_plot(par = den_group):
    fig = px.density_mapbox(ALZ_map, lat='start_lat',
                        lon='start_lng',
                        z=f'{par}',
                        radius=10,
                        zoom=3)
    fig.update_layout(mapbox_style="open-street-map")
    fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
    return st.plotly_chart(fig, use_container_width=True)
den_plot(den_group)

st.markdown('
',unsafe_allow_html=True)
st.markdown('##### Authors: Nino Yao & Linh Nguyen')


text:
from scipy.optimize import leastsq
from copy import deepcopy
import numpy as np
import warnings

def standardize_vector(vector):
    if vector[0] != 0:
        if vector[0] < 0:
            vector = np.array(vector) * -1
            vector = vector.tolist()
    elif vector[1] != 0:
        if vector[1] < 0:
            vector = np.array(vector) * -1
            vector = vector.tolist()
    else:
        if vector[2] < 0:
            vector = np.array(vector) * -1
            vector = vector.tolist()

    for i in range(3):
        vector[i] = vector[i] + 0

    return vector

def is_rasci_transition(configuration, reference, n_electron=1, max_jump=10):
    """
    Determine if a configuration corresponds to a transition of n_electron

    :param configuration: dictionary containing the configuration to be analyzed
    :param reference: reference configuration (in general lowest energy Slater determinant)
    :param n_electron:
    :param max_jump: Restrict to transitions with jumps less or equal to max_jump orbitals

    :return: True if conditions are met, otherwise False
    """

    warnings.warn('This function will be deprecated, use "is_transition" instead', DeprecationWarning)

    alpha_diff = [int(i) - int(j) for i, j in zip(configuration['alpha'], reference['alpha'])]
    beta_diff = [int(i) - int(j) for i, j in zip(configuration['beta'], reference['beta'])]

    ini_alpha = np.where(np.array(alpha_diff) < 0)[0]
    fin_alpha = np.where(np.array(alpha_diff) > 0)[0]

    ini_beta = np.where(np.array(beta_diff) < 0)[0]
    fin_beta = np.where(np.array(beta_diff) > 0)[0]

    try:
        jump_alpha = np.max(fin_alpha) - np.min(ini_alpha)
    except ValueError:
        jump_alpha = 0

    try:
        jump_beta = np.max(fin_beta) - np.min(ini_beta)
    except ValueError:
        jump_beta = 0

    n_alpha = len(fin_alpha)
    n_beta = len(fin_beta)

    elec_condition = n_alpha + n_beta == n_electron
    jump_condition = jump_alpha <= max_jump and jump_beta <= max_jump

    return elec_condition and jump_condition

def get_ratio_of_condition_rasci(state, n_electron=1, max_jump=10):
    # reference = {'hole': '', 'alpha': '111000', 'beta': '111000', 'part': '', 'amplitude': 0.9777044}

    warnings.warn('This function will be deprecated, use "get_ratio_of_condition" instead', DeprecationWarning)
    alpha_int = [int(i) for i in state['configurations'][0]['alpha']]
    ref_alpha = ''
    for i in range(len(alpha_int)):
        if i < np.sum(alpha_int):
            ref_alpha += '1'
        else:
            ref_alpha += '0'

    reference = {'hole': '', 'alpha': ref_alpha, 'beta': ref_alpha, 'part': ''}

    p = 0
    for configuration in state['configurations']:
        if is_rasci_transition(configuration, reference, n_electron, max_jump):
            p += configuration['amplitude']**2

    return p

def is_transition(configuration, reference, n_electron=1, max_jump=10):
    """
    Determine if a configuration corresponds to a transition of n_electron

    :param configuration: dictionary containing the configuration to be analyzed
    :param reference: reference configuration (in general lowest energy Slater determinant)
    :param n_electron: number of electrons in the transition
    :param max_jump: Restrict to transitions with jumps less or equal to max_jump orbitals

    :return: True if conditions are met, otherwise False
    """

    alpha_diff = [int(i) - int(j) for i, j in zip(configuration['occupations']['alpha'], reference['alpha'])]
    beta_diff = [int(i) - int(j) for i, j in zip(configuration['occupations']['beta'], reference['beta'])]

    ini_alpha = np.where(np.array(alpha_diff) < 0)[0]
    fin_alpha = np.where(np.array(alpha_diff) > 0)[0]

    ini_beta = np.where(np.array(beta_diff) < 0)[0]
    fin_beta = np.where(np.array(beta_diff) > 0)[0]

    try:
        jump_alpha = np.max(fin_alpha) - np.min(ini_alpha)
    except ValueError:
        jump_alpha = 0

    try:
        jump_beta = np.max(fin_beta) - np.min(ini_beta)
    except ValueError:
        jump_beta = 0

    n_alpha = len(fin_alpha)
    n_beta = len(fin_beta)

    elec_condition = n_alpha + n_beta == n_electron
    jump_condition = jump_alpha <= max_jump and jump_beta <= max_jump

    return elec_condition and jump_condition

def get_ratio_of_condition(state, n_electron=1, max_jump=10, ground_state_configuration=None):
    # reference = {'hole': '', 'alpha': '111000', 'beta': '111000', 'part': '', 'amplitude': 0.9777044}

    n_alpha = np.sum(state['configurations'][0]['occupations']['alpha'])
    n_beta = np.sum(state['configurations'][0]['occupations']['beta'])
    n_orb = len(state['configurations'][0]['occupations']['alpha'])

    if ground_state_configuration is None:
        reference = {'alpha': [1] * n_alpha + [0] * (n_orb - n_alpha),
                     'beta': [1] * n_beta + [0] * (n_orb - n_beta)}
    else:
        reference = ground_state_configuration

    p = 0
    for configuration in state['configurations']:
        if is_transition(configuration, reference, n_electron, max_jump):
            p += configuration['amplitude']**2

    return p

def _set_zero_to_coefficients(basis, mo_coeff, range_atoms):
    """
    set 0.0 to coefficients of functions centered in atoms 'range_atoms'

    :param basis: full basis dictionary
    :param mo_coeff: full molecular orbitals coefficients to be modiffied
    :param range_atoms: list containing the atom numbers whose coefficients will be set to zero
    :return:
    """

    functions_to_atom = []
    nat = len(basis['atoms'])
    for i in range(0, nat):
        nf = 0
        for shell in basis['atoms'][i]['shells']:
            nf += shell['functions']
        functions_to_atom.append(nf)
    functions_to_atom = functions_to_atom

    # print(funtions_to_atom)
    mo_coeff_a = np.array(mo_coeff['alpha'])
    for i in range_atoms:
        ini = np.sum(functions_to_atom[:i], dtype=int)
        fin = np.sum(functions_to_atom[:i+1], dtype=int)
        # print('ini', ini, 'fin', fin)
        mo_coeff_a[:, ini: fin] *= 0.0
    mo_coeff_zero = {'alpha': mo_coeff_a.tolist()}

    if 'beta' in mo_coeff:
        mo_coeff_b = np.array(mo_coeff['beta'])
        for i in range_atoms:
            ini = np.sum(functions_to_atom[:i], dtype=int)
            fin = np.sum(functions_to_atom[:i + 1], dtype=int)
            # print('ini', ini, 'fin', fin)
            mo_coeff_b[:, ini: fin] *= 0.0
        mo_coeff_zero['beta'] = mo_coeff_b.tolist()

    return mo_coeff_zero

def crop_electronic_structure(electronic_structure, atom_list, renormalize=True):

    n_atoms = electronic_structure['structure'].get_number_of_atoms()

    complementary_list = [i for i in range(n_atoms) if not i in atom_list]

    new_coefficients = _set_zero_to_coefficients(electronic_structure['basis'],
                                                 electronic_structure['coefficients'],
                                                 complementary_list)

    if renormalize:
        if 'overlap' not in electronic_structure:
            raise Exception('Overlap matrix not found')

        overlap = electronic_structure['overlap']

        def renomalize_coefficients(original_coeff, activate_test=False):

            dot = np.dot(original_coeff, np.dot(overlap, np.transpose(original_coeff)))
            norm_vect = np.diag(dot)

            def normalize_vector(vector, norm):
                if norm > 1e-8:
                    return list(np.array(vector)/np.sqrt(norm))
                else:
                    return np.zeros_like(vector).tolist()

            coeff = np.array([ normalize_vector(mo, norm) for mo, norm in zip(original_coeff, norm_vect)])

            if activate_test:
                print('-Norm Test-')
                dot = np.dot(coeff, np.dot(overlap, coeff.T))
                norm_vect = np.diag(dot)
                print(norm_vect)

            return coeff

        new_coefficients['alpha'] = renomalize_coefficients(new_coefficients['alpha'])
        if 'beta' in new_coefficients:
            new_coefficients['beta'] = renomalize_coefficients(new_coefficients['beta'])

    new_electronic_structure = deepcopy(electronic_structure)
    new_electronic_structure['coefficients'] = new_coefficients
    return new_electronic_structure

def get_plane(coords, direction=None):
    """
    Returns the center and normal vector of tha plane formed by a list of atomic coordinates

    :param coords: List of atomic coordinates

    :return: center, normal_vector
    """

    coords = np.array(coords)
    p0 = np.cross(coords[0] - coords[2], coords[0] - coords[-1]) / np.linalg.norm(np.cross(coords[0] - coords[2],
                                                                                coords[0] - coords[-1]))

    # Fitting function to a plane
    def fitfunc(p, coords):
        average = np.average(coords, axis=0)
        return np.array([np.dot(p, average - c) for c in coords])

    # Error function (including force norm(normal) = 1)
    errfunc = lambda p, x: fitfunc(p, x)**2 + (np.linalg.norm(p) - 1.0)**2

    p1, flag = leastsq(errfunc, p0, args=(coords,))

    # Check final result
    point = np.average(coords, axis=0).tolist()
    normal = np.array(p1)/np.linalg.norm(p1)

    if direction is not None:
        vector = coords[direction[1]] - coords[direction[0]]
        # proj = vector - np.dot(vector, normal)*normal
        projected = np.cross(normal,  np.cross(vector, normal))
        projected /= np.linalg.norm(projected)

        normal = standardize_vector(normal)
        projected = standardize_vector(projected)

        return point, normal, projected

    normal = standardize_vector(normal)
    return point, normal

def reorder_coefficients(occupations, coefficients):
    """
    Reorder the coefficients according to occupations. Occupated orbitals will be grouped at the beginning
    non occupied will be attached at the end

    :param occupations: list on integers (0 or 1) or list of Boolean
    :param coefficients:  dictionary containing the molecular orbitals coefficients {'alpha': coeff, 'beta:' coeff}.
                          coeff should be a list of lists (Norb x NBas)
    :return:
    """

    alpha_coefficients = []
    non_occupied = []
    for occ, coeff in zip(occupations['alpha'], coefficients['alpha']):
        if occ:
            alpha_coefficients.append(coeff)
        else:
            non_occupied.append(coeff)

    # non occupated attached at the end
    alpha_coefficients += non_occupied

    if not 'beta' in coefficients:
        coefficients['beta'] = coefficients['alpha']

    beta_coefficients = []
    non_occupied = []
    for occ, coeff in zip(occupations['beta'], coefficients['beta']):
        if occ:
            beta_coefficients.append(coeff)
        else:
            non_occupied.append(coeff)

    # non occupated attached at the end
    beta_coefficients += non_occupied

    return {'alpha': alpha_coefficients, 'beta': beta_coefficients}

def get_occupied_electrons(configuration, structure):
    # works for closed shell only
    alpha_e = np.sum([int(c) for c in configuration['alpha']])
    beta_e = np.sum([int(c) for c in configuration['beta']])
    hole = 0 if configuration['hole'] == '' else 1
    part = 0 if configuration['part'] == '' else 1

    return (structure.number_of_electrons + structure.charge - (alpha_e + beta_e + part - hole))//2

def get_inertia(structure):
    """
    returns the inertia moments and main axis of inertia (in rows)

    :param structure: Structure object containg the molecule

    :return: eigenvalues, eigenvectors
    """

    coordinates = structure.get_coordinates()
    masses = structure.get_atomic_masses()

    coordinates = np.array(coordinates)

    cm = np.average(coordinates, axis=0, weights=masses)

    inertia_tensor = np.zeros((3, 3))
    for c, m in zip(coordinates, masses):
        inertia_tensor += m * (np.dot(c-cm, c-cm) * np.identity(3) - np.outer(c-cm, c-cm))

    eval, ev = np.linalg.eigh(inertia_tensor)

    return eval.tolist(), ev.T.tolist()

def get_basis_functions_ranges_by_atoms(basis, atoms_range=None):

    num = 0
    functions_range = []
    for atoms in np.array(basis['atoms']):
        ini = num
        for shell in atoms['shells']:
            num += shell['functions']
        fin = num
        functions_range.append((ini, fin))

    if atoms_range is not None:
        functions_range = np.array(functions_range)[atoms_range]

    return functions_range

def classify_diabatic_states_of_fragment(diabatic_states, fragments_atoms, tol=0.1):

    print('     Attach      Detach')

    types = []
    for i, state in enumerate(diabatic_states):

        sum_attach = np.sum([state['mulliken']['attach'][i] for i in fragments_atoms])
        sum_detach = np.sum([state['mulliken']['detach'][i] for i in fragments_atoms])

        type = 'unknown'
        if np.abs(sum_attach) > 1.0 - tol:
            if np.abs(sum_detach) < tol:
                type = 'CT+'
            else:
                type = 'LE'
        elif np.abs(sum_attach) < tol:
            if np.abs(sum_detach) > 1 - tol:
                type = 'CT-'

        print('{} {:10.5f} {:10.5f} {}'.format(i + 1, sum_attach, sum_detach, type))
        types.append(type)

    return types

def get_occupated_list(configuration, structure, total_orbitals):
    import numpy as np
    occupied_orbitals = get_occupied_electrons(configuration, structure)
    n_extra = total_orbitals - occupied_orbitals - len(configuration['alpha'])
    vector_alpha = [1] * occupied_orbitals + [int(c) for c in configuration['alpha']] + [0] * n_extra

    n_extra = total_orbitals - occupied_orbitals - len(configuration['beta'])
    vector_beta = [1] * occupied_orbitals + [int(c) for c in configuration['beta']] + [0] * n_extra

    if configuration['hole'] != '':
        if np.sum(vector_alpha) > np.sum(vector_beta):
            vector_alpha[int(configuration['hole']) - 1] = 0
        else:
            vector_beta[int(configuration['hole']) - 1] = 0

    if configuration['part'] != '':
        if np.sum(vector_alpha) < np.sum(vector_beta):
            vector_alpha[int(configuration['part']) - 1] = 1
        else:
            vector_beta[int(configuration['part']) - 1] = 1

    return {'alpha': vector_alpha, 'beta': vector_beta}

reason: import numpy,from scipy


text:
#!/usr/bin/python

from pymc import *
import numpy as np

tflops_array = np.array(map(int, open("data.points").readlines()))

tflops_mean  = Normal('tflops_mean', mu=np.average(tflops_array),
                      tau=1.0/(5000.0**2.0))

tflops = Normal('tflops', mu=tflops_mean, tau=1.0/(1000**2.0),
                value=tflops_array, observed=True)

tflops_next = Normal('tflops_next', mu=tflops_mean, tau=1.0/(1000**2.0))

@deterministic()
def hit30001(tflops=tflops_next):
    return tflops>=30001

model = Model([hit30001, tflops_next])

M = MCMC(model)
M.sample(iter=50000, burn=5000)
M.summary()

max_stars_repo_name: jkominek/scicasting

max_issues_repo_name: jkominek/scicasting

max_forks_repo_name: jkominek/scicasting


text:
from statistics import mode

import cv2
import matplotlib.pyplot as plt
from keras.models import load_model
from keras.preprocessing import image
import numpy as np

from utils.datasets import get_labels

def detect_faces(detection_model, gray_image_array):
    return detection_model.detectMultiScale(gray_image_array, 1.3, 5)

def draw_text(coordinates, image_array, text, color, x_offset=0, y_offset=0,
                                                font_scale=2, thickness=2):
    x, y = coordinates[:2]
    cv2.putText(image_array, text, (x + x_offset, y + y_offset),
                cv2.FONT_HERSHEY_SIMPLEX,
                font_scale, color, thickness, cv2.LINE_AA)

def draw_bounding_box(face_coordinates, image_array, color):
    x, y, w, h = face_coordinates
    cv2.rectangle(image_array, (x, y), (x + w, y + h), color, 2)

def apply_offsets(face_coordinates, offsets):
    x, y, width, height = face_coordinates
    x_off, y_off = offsets
    return (x - x_off, x + width + x_off, y - y_off, y + height + y_off)

def load_detection_model(model_path):
    detection_model = cv2.CascadeClassifier(model_path)
    return detection_model

def preprocess_input(x, v2=True):
    x = x.astype('float32')
    x = x / 255.0
    if v2:
        x = x - 0.5
        x = x * 2.0
    return x

# parameters for loading data and images
detection_model_path = '../trained_models/detection_models/haarcascade_frontalface_default.xml'
emotion_model_path = '../trained_models/emotion_models/fer2013_mini_XCEPTION.102-0.66.hdf5'
emotion_labels = get_labels('fer2013')

# hyper-parameters for bounding boxes shape
frame_window = 10
emotion_offsets = (20, 40)

# loading models
face_detection = load_detection_model(detection_model_path)
emotion_classifier = load_model(emotion_model_path, compile=False)

# getting input model shapes for inference
emotion_target_size = emotion_classifier.input_shape[1:3]

# starting lists for calculating modes
emotion_window = []

# starting video streaming
cv2.namedWindow('window_frame')
video_capture = cv2.VideoCapture(0)
while True:
    bgr_image = video_capture.read()[1]
    gray_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2GRAY)
    rgb_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2RGB)
    faces = detect_faces(face_detection, gray_image)

    for face_coordinates in faces:

        x1, x2, y1, y2 = apply_offsets(face_coordinates, emotion_offsets)
        gray_face = gray_image[y1:y2, x1:x2]
        try:
            gray_face = cv2.resize(gray_face, (emotion_target_size))
        except:
            continue

        gray_face = preprocess_input(gray_face, True)
        gray_face = np.expand_dims(gray_face, 0)
        gray_face = np.expand_dims(gray_face, -1)
        emotion_prediction = emotion_classifier.predict(gray_face)
        emotion_probability = np.max(emotion_prediction)
        emotion_label_arg = np.argmax(emotion_prediction)
        emotion_text = emotion_labels[emotion_label_arg]
        emotion_window.append(emotion_text)

        if len(emotion_window) > frame_window:
            emotion_window.pop(0)
        try:
            emotion_mode = mode(emotion_window)
        except:
            continue

        if emotion_text == 'angry':
            color = emotion_probability * np.asarray((255, 0, 0))
        elif emotion_text == 'sad':
            color = emotion_probability * np.asarray((0, 0, 255))
        elif emotion_text == 'happy':
            color = emotion_probability * np.asarray((255, 255, 0))
        elif emotion_text == 'surprise':
            color = emotion_probability * np.asarray((0, 255, 255))
        else:
            color = emotion_probability * np.asarray((0, 255, 0))

        color = color.astype(int)
        color = color.tolist()

        draw_bounding_box(face_coordinates, rgb_image, color)
        draw_text(face_coordinates, rgb_image, emotion_mode,
                  color, 0, -45, 1, 1)

    bgr_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR)
    cv2.imshow('window_frame', bgr_image)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
video_capture.release()
cv2.destroyAllWindows()