예제 #1
0
def filtered_dict(img, 
    low =SNS(h=15, vx=20, vx_yel=10, sx=10, s=75, v=175), #bad @4sec challenge if s=80,v=180
    high=SNS(h=35, vx=120,vx_yel=60, sx=100)):
    ''' 
    Returns dict of 7 filtered channels on img of:
    'yel': yellow filter via h channel
    'white': white filter via s channel
    'white2': white filter with narrower thresholds
    'posEdge': possitive sobelx via v channel
    'negEdge': negative sobelx via v channel
    'yelPos': possitive sobelx via s channel for yellow
    'yelNeg': negative sobelx via s channel for yellow
    (all h,s,v channels are of hsv space)
    '''
    d = {}  
    
    hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV).astype(np.float)
    h_ch = hsv[:,:,0]
    s_ch = hsv[:,:,1]
    v_ch = hsv[:,:,2]

    ## color thresholds
    d['yel'] = np.zeros_like(h_ch)
    d['yel'][(h_ch >= low.h) & (h_ch <= high.h) & (s_ch >= low.s)] = 1

    d['white'] = np.zeros_like(v_ch)
    d['white'][(v_ch >= low.v+s_ch+20)] = 1

    d['white2'] = np.copy(d['white'])
    d['white2'][v_ch >= low.v+s_ch] = 1

    ## edge with sobel
    vx_pos = cv2.Sobel(v_ch, cv2.CV_64F, 1, 0, ksize=3)
    vx_pos[vx_pos <= 0] = 0
    vx_pos = scale_255(vx_pos)

    vx_neg = np.copy(vx_pos)
    vx_neg[vx_neg > 0] = 0
    vx_neg = np.absolute(vx_neg)
    vx_neg = scale_255(vx_neg)

    d['posEdge'] = np.zeros_like(vx_pos)
    d['posEdge'][(vx_pos >= low.vx) & (vx_pos <= high.vx)] = 1

    d['negEdge'] = np.zeros_like(vx_neg)
    d['negEdge'][(vx_neg >= low.vx) & (vx_neg <= high.vx)] = 1

    sobelx = cv2.Sobel(s_ch, cv2.CV_64F, 1, 0, ksize=3)
    sobelx = np.absolute(sobelx)
    sobelx = scale_255(sobelx)

    d['yelPos'] = np.zeros_like(sobelx)
    d['yelPos'][(sobelx >= low.sx) & (sobelx <= high.sx) 
              & (vx_pos >= low.vx_yel) & (vx_pos <= high.vx_yel)] = 1

    d['yelNeg'] = np.zeros_like(sobelx)
    d['yelNeg'][(sobelx >= low.sx) & (sobelx <= high.sx) 
              & (vx_neg >= low.vx_yel) & (vx_neg <= high.vx_yel)] = 1           
    return d
예제 #2
0
def fixClassHook():
    aRecord = []

    class C1(BaseClass):
        @hook('hook1')
        def f2(self, a=0):
            aRecord.append(self)
            aRecord.append(a + 2)

    class C2(BaseClass):
        @hook('hook1')
        def f3(self, a=0):
            aRecord.append(self)
            aRecord.append(a + 3)

    class C1a(C2, C1):
        @hook('hook1')
        def f1(self, a=0):
            aRecord.append(self)
            aRecord.append(a + 1)

    class C1b(C1a):
        @hook('hook1', atTop=True)
        def f6(self, a=0):
            aRecord.append(self)
            aRecord.append(a + 6)

    return SNS(aRecord=aRecord, C1=C1, C2=C2, C1a=C1a, C1b=C1b)
def fixLogger(fs, request):
    class ClassLog(UnladenWithLogging):
        def args(cls, parser):
            parser.add_argument('--num', type=int, default=0)

        def main(self, ns):
            self.logger.debug('maindebug.{:d}'.format(ns.num))

    return SNS(fs=fs, ClassLog=ClassLog, fname=request.param)
예제 #4
0
def color_hist(img, bins=32, ranges=[(0,256)]*3):
    ch1 = np.histogram(img[:, :, 0], bins=bins, range=ranges[0])
    ch2 = np.histogram(img[:, :, 1], bins=bins, range=ranges[1])
    ch3 = np.histogram(img[:, :, 2], bins=bins, range=ranges[2])
    chs = [ch1, ch2, ch3]
    return SNS(
        hist=np.concatenate([ch[0] for ch in chs]),
        bin_edges=np.concatenate([ch[1] for ch in chs]),
    )
예제 #5
0
    def runcmd(self, args=()):
        # Deliberately not putting this into args, so there won't be default value in args
        if len(args) > 0 and args[0] == '--version':
            print(get_distribution('unladen-chant').version)
            sys.exit(0)

        self.invokeHook('preParse', args)
        ns = self.parser.parse_args(args, namespace=SNS(**self._defaults))
        self.run(**vars(ns))
예제 #6
0
def fixTimer(fs, request):
    class ClassTimer(UnladenWithTiming):
        def main(self, ns):
            pass

    class ClassTimer2(UnladenWithTiming):
        def main(self, ns):
            ClassTimer().runcmd(('--colorful-header', ))

    return SNS(fs=fs, ClassTimer=ClassTimer, ClassTimer2=ClassTimer2)
예제 #7
0
def filteredPixels(filtereds):
    ''' Returns nonzero pixels object for filters in filtereds in x and y dims.
    filtereds: warped filters dict (see filtered_dict() for list of filters)
    '''
    o = SNS(x={}, y={})
    for fltr in filtereds:
        nonzero = filtereds[fltr].nonzero()
        o.x[fltr] = np.array(nonzero[1])
        o.y[fltr] = np.array(nonzero[0])
    return o
예제 #8
0
def fixReturnHook():
    class C(BaseClass):
        @hook('hook1')
        def f(self):
            return self

        @hook('hook1')
        def f2(self):
            return "f2"

    return SNS(C=C, o=C())
예제 #9
0
def pxObj():
    ''' Returns object of:
    x:  array of L/R pixels in x coordinates
    y:  array of L/R pixels in y coordinates
    found: array of L/R line found boolean
    '''
    return SNS(
        x = [None, None],
        y = [None, None],
        found = [False, False]
    )
예제 #10
0
def fixListNs():
    mNs = {}

    class ClassListNs(UnladenWithCmdline):
        def main(self, ns):
            mNs.update(vars(ns))

    class ClassParse(ClassListNs):
        def args(cls, parser):
            parser.add_argument('--option', '-o', type=int, default=15)

    return SNS(mNs=mNs, ClassListNs=ClassListNs, ClassParse=ClassParse)
예제 #11
0
def fixSimpleHook():
    aRecord = []

    class C(BaseClass):
        @hook('hook1')
        def f(self):
            aRecord.append(self)

    def f0(self, a=0):
        aRecord.append(0)

    return SNS(aRecord=aRecord, C=C, o=C(), f0=f0)
예제 #12
0
def hog_vis(img,
    orientations=8,
    pxs_per_cell=8,
    cells_per_blk=2,
    feature_vector=False):
    ''' Histogram of Oriented Gradients, visualise=True 
    '''
    result = skFeat.hog(img,
        orientations=orientations,
        pixels_per_cell=(pxs_per_cell,pxs_per_cell),
        cells_per_block=(cells_per_blk,cells_per_blk),
        transform_sqrt=True, visualise=True, feature_vector=feature_vector
    )
    return SNS(
        features=result[0],
        images=result[1],
    )
def fixtureFlowCheck():
    aRecord = []

    class TaskBasic(UnladenTaskBase):
        def main(self, ns):
            aRecord.append('main' + str(getattr(ns, 'a', 0)))
            return True

    class TaskWithHooks(TaskBasic):
        @hook('preMain')
        def preMain1(self, ns):
            aRecord.append('pre' + str(getattr(ns, 'a', 0)))
            return True

        @hook('postMain')
        def postMain1(self, ns):
            aRecord.append('post' + str(getattr(ns, 'a', 0)))
            return True

    return SNS(aRecord=aRecord,
               TaskBasic=TaskBasic,
               TaskWithHooks=TaskWithHooks)
예제 #14
0
import numpy as np
import cv2, time
from sklearn.externals import joblib

from lib.detection import *
from config import pklpath, default, defaults
from types import SimpleNamespace as SNS

from moviepy.editor import VideoFileClip

t = time.time()
model = SNS(
    classifier=joblib.load(pklpath.svc),
    scaler=joblib.load(pklpath.scaler),
    train_size=default.train_size,
    defaults=defaults,
)
detector = CarDetector(model, (720, 1280))


def process_image(img):
    return detector.detected_image(img)


# video_in = False
# video_in = 'video-in/test1.mp4'
# video_in = 'video-in/prob6.mp4'  #ffmpeg -i project_video.mp4 -ss 00:00:13 -codec copy -t 6 prob6.mp4
# video_in = 'video-in/prob8.mp4'  #ffmpeg -i project_video.mp4 -ss 00:00:38.4 -codec copy -t 8 prob8.mp4
# video_in = 'video-in/prob9.mp4'  #ffmpeg -i project_video.mp4 -ss 00:00:10.8 -codec copy -t 9 prob9.mp4
# video_in = 'video-in/prob10.mp4' #ffmpeg -i project_video.mp4 -ss 00:00:22.8 -codec copy -t 10 prob10.mp4
video_in = 'video-in/project_video.mp4'
예제 #15
0
        self.fit += coef[poly_order]  # one more += for _0_to_ht**0
        self.coef = coef

        if self.fit_MA == None:
            self.set_all(False)
        self.set_center_and_curve_radius(self.coef)

    def fit_vs_MA(self):
        ''' Returns norm of difference of current fit x positions vs. its MA
        '''
        return linNorm(self.fit - self.fit_MA)


_max = SNS(
    fitdiff=1700,  # poor left lane fit if < 1700 on project vid @38sec
    fit_err=80,
    fail=2,
)


def bad_fit_diff(lf_coef, rt_coef, lf_radius, rt_radius, min_radm=1000):
    ''' Returns if the difference between coefs of left and right fits are more 
        than an order of magnitude than expected.
    min_radm: Min expected radius in meters. Adjust to actual min of road radius.
    '''
    lf_coef = np.array(lf_coef)
    rt_coef = np.array(rt_coef)
    fitdiff = lf_coef - rt_coef
    min_of_2 = np.minimum(np.absolute(lf_coef), np.absolute(rt_coef))
    expected = (min_radm * 2) / (abs(lf_radius) + abs(rt_radius))
    return linNorm(fitdiff[:2] / min_of_2[:2]) * expected > 10
예제 #16
0
from glob import glob
from os.path import join
from types import SimpleNamespace as SNS

pklpath = SNS(
    svc='models/svc-all3-hog12-luv.pkl',
    scaler='models/scaler-all3-hog12-luv.pkl',
    # svc='models/svc.pkl',
    # scaler='models/scaler.pkl',
)
imgspath = '../data'
cars_imgspath = glob(join(imgspath, 'vehicles', '*/*.png'))
notcars_imgspath = glob(join(imgspath, 'non-vehicles', '*/*.png'))

default = SNS(
    # color_space='YCrCb',  # Can be RGB, HSV, LUV, HLS, YUV, YCrCb(tried, not good)
    # orient = 10,  # HOG orientations, 10 misses much more than 12
    color_space='LUV',  # Can be RGB, HSV, LUV, HLS, YUV, YCrCb(tried, not good)
    orient=12,  # HOG orientations, 10 misses much more than 12
    pix_per_cell=8,  # HOG pixels per cell
    cell_per_block=2,  # HOG cells per block
    hog_channel='ALL',  # Can be 0, 1, 2, or "ALL"
    train_size=(64, 64),  # train image size
    spatial_size=(32, 32),  # Spatial binning dimensions
    hist_bins=32,  # Number of histogram bins
    hog_feat=True,
    hist_feat=True,  # worst if no hist
    spatial_feat=True,  # much worst if no spatial
)
defaults = {
    'color_space': default.color_space,
예제 #17
0
import numpy as np
import cv2, json
from types import SimpleNamespace as SNS

with open('camera_cal.json', 'r') as f:
    global cam
    camera = json.load(f)
    cam = SNS(
        mtx=np.array(camera['mtx']),
        dist=np.array(camera['dist']),
    )


def undistort(img):
    return cv2.undistort(img, cam.mtx, cam.dist, None, cam.mtx)
 def run(self, **kwargs):
     return self.runWithNs(SNS(**kwargs))
예제 #19
0

def cars_coords_str(cars):
    return ' '.join([car.coords_str for car in cars])


def coords_gen(wins, txt=''):
    return ('; '.join(['x0=%d, wd=%d' % (_x0(win), _wd(win)) for win in wins]))


## Settings for side wins
dbg = SNS(
    crop = { # these settings work with 4,6,7 lines of btm text, fails on 5 lines
        'top':350,
        'btm':30,
        'left':0,
        'right':0,
    },
    wins_cnt = 3,
)

_colors = [(255, 0, 0), (0, 0, 255), (0, 255, 0)]


def _color(i):
    return _colors[i % len(_colors)]


car_labels = string.ascii_uppercase[:26]

예제 #20
0
def xyfound(roi, filtereds, filteredPxs, img, windows=True,
    minpct={'cnt':.011, 'white':.011, 'yel':.032},
    maxpct={'cnt':1.1, 'white2':.88, 'white2InWins':.22, 'white':.55, 'whiteInWins':.055},
    minpxs=None, maxpxs=None):
    ''' Returns tuple of (x-coords, y-coords, found, filters-used) of lane detection

    roi: ROI of dict of different filtered pixels
    filtereds: warped filters dict (see filtered_dict() for list of filters)
    filteredPxs: filteredPixels() result
    windows: full detection via windows or not
    minpct, maxpct: min/max pixels % of total image pixels thresholds dict
    minpxs, maxpxs: min/max pixels thresholds dict, overrides minpct/maxpct
    '''
    nPixels = img.shape[0]*img.shape[1]

    # calc min and max pxs from pct params
    if not minpxs:
        minpxs = {}
        for k,v in minpct.items():
            minpxs[k] = int(v*.01*nPixels)
    minpx = SNS(**minpxs)

    if not maxpxs:
        maxpxs = {}
        for k,v in maxpct.items():
            maxpxs[k] = int(v*.01*nPixels)
    maxpx = SNS(**maxpxs)

    # global printThresholds
    # if printThresholds:
    #     print('Min Thresholds used:', minpxs)
    #     print('Max Thresholds used:', maxpxs)
    # printThresholds = False

    pxCnt, mean, stdev = {}, {}, {}
    for fltr in filtereds: 
        _pxCnt = np.sum(roi[fltr])
        if _pxCnt < minpx.cnt or (windows and _pxCnt > maxpx.cnt):
            continue
        pxCnt[fltr] = _pxCnt
        mean[fltr]  = np.mean(filteredPxs.x[fltr][roi[fltr]])
        stdev[fltr] = np.std(filteredPxs.x[fltr][roi[fltr]])
    
    filters = pxCnt.keys()
    pxCnt = SNS(**pxCnt)

    if windows:
        used = [c for c in filters if stdev[c]<35]
    else:
        used = [c for c in filters]

    # remove poor filters
    if 'posEdge' in used:
        if 'negEdge' not in filters:
            used.remove('posEdge')

    if 'yelPos' in used:
        if 'yelNeg' not in filters:
            used.remove('yelPos')

    if ('white2' in used):
        if 'white' in used:
            used.remove('white')
        if pxCnt.white2 > maxpx.white2 or (windows and pxCnt.white2 > maxpx.white2InWins):
            used.remove('white2')

    if 'white' in used and (pxCnt.white < minpx.white or pxCnt.white > maxpx.white):
        used.remove('white')

    if windows and 'white' in used and pxCnt.white > maxpx.whiteInWins:
        used.remove('white')

    if 'yel' in used and pxCnt.yel < minpx.yel:
        used.remove('yel')
    
    # combine all used channels
    combine_x, combine_y = [],[]
    for fltr in used:
        combine_x.append(filteredPxs.x[fltr][roi[fltr]])
        combine_y.append(filteredPxs.y[fltr][roi[fltr]])
    if combine_x:
        return np.concatenate(combine_x), np.concatenate(combine_y), True, used
    else:
        return None, None, False, used
예제 #21
0
    def findlinepixs(self, nwindows=10):
        ''' Find lane lines with mean and stddev via sliding windows
            Sets self.pxs to pxsObj() of result
        '''
        filtereds, wht, yel = warpedChannels(filtered_dict(self.img), self)
        self.init_side_wins(wht, yel)

        win_ht = self.img_ht//nwindows
        qtr_wd = self.img_wd//4
        _3qtrs = qtr_wd*3
        default_margin = 150

        margin = [qtr_wd, qtr_wd]
        x_mean = [qtr_wd, _3qtrs]
        prvx_mean = [qtr_wd, _3qtrs]
        prvx = [None, None] # save prvx_mean if it's good
        
        pixels = filteredPixels(filtereds) 
        pxs = pxsObj()
        lanes_gap = self.img_wd//2
        momentum = [0, 0]
        last_update = [0, 0]

        # Step through the windows one by one
        for i in range(nwindows):

            # window boundaries
            wb = SNS(
                x0 = [int(x_mean[side] - margin[side]) for side in LR],
                x1 = [int(x_mean[side] + margin[side]) for side in LR],
                y0 = self.img_ht - (i+1)*win_ht,
                y1 = self.img_ht - i*win_ht,
            )
            px, used = filteredBoundsPxObj(wb, filtereds, pixels, self.img)

            if noLaneFound(lanes_gap, x_mean, self.img_wd):
                break

            gap = min(lanes_gap, self.img_wd//2)
            if px.found[L] or px.found[R]:
                margin[L] = 50 if px.found[L] else 150
                margin[R] = 50 if px.found[R] else 150
                x_mean[L] = np.mean(px.x[L]) if px.found[L] else np.mean(px.x[R]) - gap
                x_mean[R] = np.mean(px.x[R]) if px.found[R] else np.mean(px.x[L]) + gap
                for side in LR:
                    x_mean[side] = np.int(x_mean[side])
                if px.found[L] or px.found[R]:
                    lanes_gap = (lanes_gap + prvx_mean[R] - prvx_mean[L])/2
            else:
                margin[L] = default_margin
                margin[R] = default_margin

                
            for side in LR:
                # Add good pixels to list
                if px.found[side]:
                    pxs.x[side].append(px.x[side])
                    pxs.y[side].append(px.y[side])
                    prvx_mean[side] = x_mean[side]
                
                # Draw the windows on the visualization image
                draw.rect(self.side_wins[0], 
                    ((wb.x0[side],wb.y0), (wb.x1[side],wb.y1)), (0,255,side*255))  
                draw.rect(self.side_wins[1], 
                    ((wb.x0[side],wb.y0), (wb.x1[side],wb.y1)), (0,255,side*255)) 
                self.side_wins[2][px.y[side], px.x[side], 2] = 255

                if px.found[side]:
                    txt = '%d'%x_mean[side]
                    txtpos = x_mean[side]-130 if len(txt)==3 else x_mean[side]-175
                    cv2.putText(self.side_wins[2], txt, (txtpos, wb.y0+win_ht-13), 
                        font, fontsize, (0,255,255), txtwd, linetype)
            
                # decide window centers based on previous windows 
                last_update[side] += 1
                if prvx[side]:
                    momentum[side] = np.int(momentum[side]) 
                    if px.found[side]:
                        momentum[side] += ((x_mean[side] - prvx[side])/(last_update[side]))//2
                if px.found[side]: 
                    prvx[side] = x_mean[side]
                    last_update[side] = 0
                x_mean[side] += momentum[side]

        for side in LR:
            if pxs.x[side]:
                pxs.found[side] = True
                pxs.x[side] = np.concatenate(pxs.x[side])
                pxs.y[side] = np.concatenate(pxs.y[side])
            else:
                pxs.x[side] = None
                pxs.y[side] = None
        self.pxs = pxs