Esempio n. 1
0
    def undistort_frame(self, frame, ofile=None, crop=False):
        if self.movie is None:
            raise ArgusError('no movie specified')
            return
        if (self.omni is None) and (self.coefficients is None):
            raise ArgusError('no distortion profile provided, Argus cannot undistort')
            return

        if not self.coefficients is None:
            map1, map2 = self.get_mappings(crop)

        if 0 <= frame - 1 <= self.frameCount - 1:
            self.movie.set(cv2.CAP_PROP_POS_MSEC, (frame - 1) * self.frame_msec)
            retval, raw = self.movie.retrieve()
            if retval:
                if crop:
                    if self.oCamUndistorter is None:
                        undistorted = cv2.remap(raw, map1, map2, cv2.INTER_LINEAR)
                    else:
                        undistorted = self.oCamUndistorter.undistort_frame(raw)
                else:
                    if self.oCamUndistorter is None:
                        undistorted = cv2.remap(raw, map1, map2,
                                                interpolation=cv2.INTER_CUBIC,
                                                borderMode=cv2.BORDER_CONSTANT,
                                                borderValue=(211, 160, 86))
                    else:
                        undistorted = self.oCamUndistorter.undistort_frame(raw)
                if not ofile is None:
                    cv2.imwrite(ofile, undistorted)
                return undistorted
            else:
                raise ArgusError('Argus could not read specified frame')
        else:
            raise ArgusError('frame out of bounds')
Esempio n. 2
0
 def get_ocam_undistorter(self):
     if not self.coefficients is None:
         if len(self.coefficients) > 8:
             ret = argus.ocam.PointUndistorter(argus.ocam.ocam_model.from_array(np.array(self.coefficients)))
             print(type(ret))
             return ret
         else:
             raise ArgusError('distortion coefficients specified are not omnidirectional')
     else:
         raise ArgusError('no distortion coefficients specified')
Esempio n. 3
0
 def get_cam_profile(self, ncams):
     if not self.coefficients is None:
         return np.array([self.coefficients for k in range(ncams)])
     else:
         raise ArgusError(
             'must specify distortion coefficients using get_coefficients or set_coefficients'
         )
Esempio n. 4
0
    def undistort_array(self, array, ofile=None, crop=False):
        if (self.omni is None) and (self.coefficients is None):
            raise ArgusError(
                'no distortion profile provided, Argus cannot undistort')
            return

        if not self.coefficients is None:
            map1, map2 = self.get_mappings(crop)

        raw = array
        if crop:
            if self.oCamUndistorter is None:
                undistorted = cv2.remap(raw, map1, map2, cv2.INTER_LINEAR)
            else:
                undistorted = self.oCamUndistorter.undistort_frame(raw)
        else:
            if self.oCamUndistorter is None:
                undistorted = cv2.remap(raw,
                                        map1,
                                        map2,
                                        interpolation=cv2.INTER_CUBIC,
                                        borderMode=cv2.BORDER_CONSTANT,
                                        borderValue=(211, 160, 86))
            else:
                undistorted = self.oCamUndistorter.undistort_frame(raw)
        if not ofile is None:
            cv2.imwrite(ofile, undistorted)
        return undistorted
Esempio n. 5
0
    def set_movie(self, fnam, copy=False):
        if copy:
            self.copy_tmp = tempfile.mkdtemp()
            cmd = [
                get_setting("FFMPEG_BINARY"),
                '-loglevel', 'panic',
                '-hide_banner',
                '-i', fnam,
                '-acodec', 'copy',
                '-vcodec', 'copy',
                os.path.join(self.copy_tmp, 'copy.mp4')]
            print('Copying video and audio codecs...')
            sys.stdout.flush()

            subprocess.call(cmd)

            print('Copy completed...')

            self.movie = cv2.VideoCapture(os.path.abspath(os.path.join(self.copy_tmp, 'copy.mp4')))
            print('Using movie at {0}'.format(os.path.join(self.copy_tmp, 'copy.mp4')))
        else:
            self.movie = cv2.VideoCapture(os.path.abspath(fnam))
            print('Using movie at ' + fnam)
        self.infilename = fnam

        try:
            self.frameCount = int(self.movie.get(cv2.CAP_PROP_FRAME_COUNT))
            self.fps = float(self.movie.get(cv2.CAP_PROP_FPS))
            self.w = int(self.movie.get(cv2.CAP_PROP_FRAME_WIDTH))
            self.h = int(self.movie.get(cv2.CAP_PROP_FRAME_HEIGHT))
            self.frame_msec = 1000. / self.fps
            return self.fps, self.frameCount
        except:
            raise ArgusError('could not read specified movie')
Esempio n. 6
0
 def set_coefficients(self, coefficients):
     if ((type(coefficients) == list) or
         (type(coefficients) == np.ndarray)) and len(coefficients) >= 8:
         self.coefficients = coefficients
     else:
         raise ArgusError(
             'inputted coefficients must be of iterable type and of length >= 8. See documentation.'
         )
Esempio n. 7
0
 def get_undistorter(self):
     if not self.coefficients is None:
         if len(self.coefficients) == 8:
             return Undistorter(coefficients=self.coefficients)
         else:
             return Undistorter(omni=self.coefficients)
     else:
         raise ArgusError('must specify distortion coefficients using get_coefficients or set_coefficients')
Esempio n. 8
0
    def get_coefficients(self, model=None, mode=None):
        if self.coefficients is None:
            if ((not model is None) and (not mode is None)):
                fnam = self.models[model]
                ifile = open(fnam, "r")
                #print 'Getting coefficients'

                line = ifile.readline().split(',')
                while line[0] != mode:
                    line = ifile.readline().split(',')
                    #print line
                    if line[0] == '':
                        break
                ifile.close()

                if line[0] == '':
                    raise ArgusError('camera model not found')
                    return
                else:
                    if not '(Fisheye)' in mode:
                        ret = [
                            line[1], line[4], line[5], line[7], line[8],
                            line[9], line[10], line[11]
                        ]
                        try:
                            ret = map(float, ret)
                            self.coefficients = ret
                        except:
                            raise ArgusError(
                                'distortion profile contains non-numbers...')
                            return
                    else:
                        try:
                            ret = map(float, line[1:])
                            self.coefficients = ret
                        except:
                            raise ArgusError(
                                'distortion profile contains non-numbers...')
                    return ret
            else:
                raise ArgusError('no mode or model specified')
        else:
            return self.coefficients
Esempio n. 9
0
    def set_movie(self, fnam):
        self.movie = cv2.VideoCapture(os.path.abspath(fnam))
        print 'Using movie at ' + fnam
        self.infilename = fnam

        try:
            self.frameCount = int(
                self.movie.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))
            self.fps = float(self.movie.get(cv2.cv.CV_CAP_PROP_FPS))
            self.frame_msec = 1000. / self.fps
            return self.fps, self.frameCount
        except:
            raise ArgusError('could not read specified movie')
Esempio n. 10
0
 def set_omnidirectional(self, omni):
     try:
         if len(omni) > 13:
             print('Making Omnidirectional mapping...')
             sys.stdout.flush()
             # self.omni = map(float, self.omni.split(',')[:])
             model = argus.ocam.ocam_model(omni[0], int(omni[1]), int(omni[2]), c=omni[3], d=omni[4], e=omni[5],
                                           xc=omni[6], yc=omni[7], pol=np.array(omni[13:]))
             self.oCamUndistorter = argus.ocam.Undistorter(model)
             self.omni = omni
         else:
             model = argus.ocam.CMei_model.from_array(np.array(omni))
             self.oCamUndistorter = argus.ocam.CMeiUndistorter(model)
             self.omni = omni
     except:
         raise ArgusError(
             'could not make omnidirectional undistorter object. make sure the omnidirectional coefficients were provided according to the documentation')
Esempio n. 11
0
    def undistort_movie(self,
                        ofnam=None,
                        frameint=25,
                        crf=12,
                        write=True,
                        display=True,
                        tmp_dir=None,
                        crop=False):
        if self.movie is None:
            raise ArgusError('no movie specified')

        if (self.omni is None) and (self.coefficients is None):
            raise ArgusError('no distortion coefficients specified')

        if tmp_dir is None:
            tmp = tempfile.mkdtemp()
        else:
            tmp = tmp_dir

        if write:
            if ofnam == '':
                raise ArgusError('no output filename specified')
            _ = ofnam.split('.')
            if _[len(_) - 1] != 'mp4' and _[len(_) - 1] != 'MP4':
                raise ArgusError('output filename must specify an mp4 file')
                return
            if os.path.isfile(ofnam):
                raise ArgusError(
                    'output file already exists! Argus will not overwrite')
                return
        try:
            t = open(self.infilename, "r")
        except:
            raise ArgusError('input movie not found')
            return

        t = None

        if not self.coefficients is None:
            map1, map2 = self.get_mappings(crop)

        # if we're displaying, make a window to do so
        if display:
            cv2.namedWindow("Undistorted", cv2.cv.CV_WINDOW_NORMAL)

        if write:
            # Create a list of the frames (pngs)
            fileList = []
        k = 1

        if display:
            cv2.startWindowThread()

        print 'Undistorting...'
        sys.stdout.flush()
        for a in range(int(self.movie.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))):
            retval, raw = self.movie.read()
            # To keep things interesting, and also not to overload the log, update users randomly somewhere between 200 to 300 frames
            if a == k:
                print "Undistorting frame number " + str(a) + " of " + str(
                    int(self.movie.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)))
                sys.stdout.flush()
                k += random.randint(200, 300)

            if retval:
                if crop:
                    if self.oCamUndistorter is None:
                        undistorted = cv2.remap(raw, map1, map2,
                                                cv2.INTER_LINEAR)
                    else:
                        undistorted = self.oCamUndistorter.undistort_frame(raw)
                else:
                    if self.oCamUndistorter is None:
                        undistorted = cv2.remap(raw,
                                                map1,
                                                map2,
                                                interpolation=cv2.INTER_CUBIC,
                                                borderMode=cv2.BORDER_CONSTANT,
                                                borderValue=(211, 160, 86))
                    else:
                        undistorted = self.oCamUndistorter.undistort_frame(raw)

                if display:
                    # Non-resizable windows in Mac OS, so make half-size so it's not too obnoxious
                    if sys.platform == 'darwin':
                        cv2.imshow(
                            'Undistorted',
                            cv2.resize(undistorted, (0, 0), fx=0.5, fy=0.5))
                    else:
                        cv2.imshow('Undistorted', undistorted)
                    cv2.waitKey(1)

                # Write the individual frame as a png to the temporary directory
                if write:
                    cv2.imwrite(tmp + '/' + str(a) + '.png', undistorted)
                    fileList.append(tmp + '/' + str(a) + '.png')
            else:
                print "Could not read frame number: " + str(a)
                print "Exiting..."
                sys.stdout.flush()
                return
        print 'Undistortion finished'
        sys.stdout.flush()
        # Destroy movie object and the window if it was even created
        movie = None
        if display:
            cv2.waitKey(1)
            cv2.destroyAllWindows()
            cv2.waitKey(1)
        if write:
            # Create a clip with the original fps from the undistorted frames in the temporary directory, read in numerical order, and set the audio to that of the original video
            print 'Reading images and beginning to encode...'
            sys.stdout.flush()
            clip = ImageSequenceClip(fileList,
                                     fps=self.fps,
                                     with_mask=False,
                                     load_images=False)
            print 'Ripping audio...'
            sys.stdout.flush()
            cmd = [
                get_setting("FFMPEG_BINARY"), '-loglevel', 'panic',
                '-hide_banner', '-i', self.infilename, '-c:a', 'copy', '-vn',
                '-sn', tmp + '/' + 'temp.m4a'
            ]
            subprocess.call(cmd)
            # Write the mp4 file
            clip.write_videofile(ofnam,
                                 fps=self.fps,
                                 audio=tmp + '/' + 'temp.m4a',
                                 audio_fps=48000,
                                 codec='libx264',
                                 threads=0,
                                 ffmpeg_params=[
                                     '-crf',
                                     str(crf), '-g',
                                     str(frameint), '-pix_fmt', 'yuv420p',
                                     '-profile', 'baseline'
                                 ])
            sys.stdout.flush()
            clip = None

            # Destroy the temporary directory
            shutil.rmtree(tmp)
Esempio n. 12
0
    def undistort_movie(self, ofnam=None, frameint=25, crf=12, write=True, display=True, tmp_dir=None, crop=False):
        if self.movie is None:
            raise ArgusError('no movie specified')

        if (self.omni is None) and (self.coefficients is None):
            raise ArgusError('no distortion coefficients specified')

        if tmp_dir is None:
            tmp = tempfile.mkdtemp()
        else:
            tmp = tmp_dir

        print(tmp)

        print('Ripping audio... \n')
        sys.stdout.flush()
        cmd = [
            get_setting("FFMPEG_BINARY"),
            '-loglevel', 'panic',
            '-hide_banner',
            '-i', self.infilename,
            '-c:a', 'copy',
            '-vn', '-sn',
            tmp + '/' + 'temp.m4a']
        subprocess.call(cmd)

        if os.path.exists(tmp + '/' + 'temp.m4a'):
            statinfo = os.stat(tmp + '/' + 'temp.m4a')

            if statinfo.st_size != 0:
                audio = tmp + '/' + 'temp.m4a'
            else:
                audio = None
        else:
            audio = None

        if audio is not None:
            cmd = [get_setting("FFMPEG_BINARY"), '-y', '-f', 'rawvideo', \
                   '-vcodec', 'rawvideo', '-s', '{0}x{1}'.format(self.w, self.h), '-pix_fmt', 'rgb24', \
                   '-r', str(self.fps), '-i', '-', '-i', audio, \
                   '-acodec', 'copy', '-vcodec', 'libx264', '-preset', 'medium', '-crf', \
                   str(crf), '-g', str(frameint), '-pix_fmt', 'yuv420p', '-profile', 'baseline', '-threads', \
                   '0', '-pix_fmt', 'yuv420p', str(ofnam)]
        else:
            cmd = [get_setting("FFMPEG_BINARY"), '-y', '-f', 'rawvideo', \
                   '-vcodec', 'rawvideo', '-s', '{0}x{1}'.format(self.w, self.h), '-pix_fmt', 'rgb24', \
                   '-r', str(self.fps), '-i', '-', '-an', \
                   '-acodec', 'copy', '-vcodec', 'libx264', '-preset', 'medium', '-crf', \
                   str(crf), '-g', str(frameint), '-pix_fmt', 'yuv420p', '-profile', 'baseline', '-threads', \
                   '0', '-pix_fmt', 'yuv420p', str(ofnam)]

        if write:
            if ofnam == '':
                raise ArgusError('no output filename specified')
            _ = ofnam.split('.')
            if _[len(_) - 1] != 'mp4' and _[len(_) - 1] != 'MP4':
                raise ArgusError('output filename must specify an mp4 file')
                return
            if os.path.isfile(ofnam):
                raise ArgusError('output file already exists! Argus will not overwrite')
                return
        try:
            t = open(self.infilename, "r")
        except:
            raise ArgusError('input movie not found')
            return

        t = None

        if not self.coefficients is None:
            map1, map2 = self.get_mappings(crop)

        # if we're displaying, make a window to do so

        print('Beginning to undistort images and compile with FFMPEG...')
        sys.stdout.flush()

        p = Popen(cmd, stdin=PIPE)

        if display:
            if 'linux' in sys.platform:
                cv2.imshow("Undistorted", np.zeros((1080, 1920, 3)))
            cv2.namedWindow("Undistorted")

        if write:
            # Create a list of the frames (pngs)
            fileList = []
        k = 1

        if display:
            if not 'linux' in sys.platform:
                cv2.startWindowThread()

        for a in range(int(self.movie.get(cv2.CAP_PROP_FRAME_COUNT))):
            retval, raw = self.movie.read()

            if retval:
                previous = raw
                if crop:
                    if self.oCamUndistorter is None:
                        undistorted = cv2.remap(raw, map1, map2, cv2.INTER_LINEAR)
                    else:
                        undistorted = self.oCamUndistorter.undistort_frame(raw)
                else:
                    if self.oCamUndistorter is None:
                        undistorted = cv2.remap(raw, map1, map2,
                                                interpolation=cv2.INTER_CUBIC,
                                                borderMode=cv2.BORDER_CONSTANT,
                                                borderValue=(211, 160, 86))
                    else:
                        undistorted = self.oCamUndistorter.undistort_frame(raw)

                if display:
                    cv2.imshow('Undistorted', cv2.resize(undistorted, (0, 0), fx=0.5, fy=0.5))
                    cv2.waitKey(1)
                undistorted = cv2.cvtColor(undistorted, cv2.COLOR_BGR2RGB)

                # im = Image.fromarray(undistorted, 'RGB')
                # im.save(p.stdin, 'PNG')

                if write:
                    p.stdin.write(undistorted.tostring())

                # line of code above allows you to open video clip after it is saved
                # without that line video clip will save but won't be able to open and play clip

                variable = False
                self.root = Tk()

                def __init__(self, master, title):
                    top = self.top = Toplevel(master)
                    top.resizable(width=FALSE, height=FALSE)
                    top.bind('<Return>', self.cleanup)
                    self.l = Label(top, text=title)
                    self.l.pack(padx=10, pady=10)
                    self.e = Entry(top)
                    self.e.focus_set()
                    self.e.pack(padx=10, pady=5)
                    self.b = Button(top, text='Ok', padx=10, pady=10)
                    self.b.bind('<Button-1>', self.cleanup)
                    self.b.pack(padx=5, pady=5)
                    self.crop = StringVar(self.root)
                    self.copy = StringVar(self.root)

                self.wrdispboth = IntVar(self.root)

                if a % 5 == 0:
                    print('\n', end='')
                    sys.stdout.flush()
                """
                # Write the individual frame as a png to the temporary directory
                if write:
                    cv2.imwrite(tmp + '/' + str(a) + '.png', undistorted)
                    fileList.append(tmp + '/' + str(a) + '.png')
                """
            else:
                if write:
                    print("Could not read frame number: " + str(a) + "\n writing blank frame")
                    p.stdin.write(np.zeros_like(previous).tostring())
                    sys.stdout.flush()
                else:
                    print("Could not read frame number: " + str(a))
                    sys.stdout.flush()

        p.stdin.close()
        p.wait()

        print('Undistortion finished')
        if write:
            print('Wrote mp4 to {0}'.format(ofnam))
        sys.stdout.flush()
        # Destroy movie object and the window if it was even created
        movie = None
        if display:
            cv2.waitKey(1)
            cv2.destroyAllWindows()
            cv2.waitKey(1)
        if write:
            # clip = ImageSequenceClip(fileList, fps=self.fps, with_mask = False, load_images = False)

            # Write the mp4 file
            """
            if os.path.exists(tmp + '/' + 'temp.m4a'):
                clip.write_videofile(ofnam, fps=self.fps, audio = tmp + '/' + 'temp.m4a', audio_fps = 48000, codec='libx264', threads=0, ffmpeg_params = ['-crf', str(crf), '-g', str(frameint), '-pix_fmt', 'yuv420p', '-profile' ,'baseline'])
            else:
                print('No audio stream found, writing without...')
                clip.write_videofile(ofnam, fps=self.fps, audio_fps = 48000, codec='libx264', threads=0, ffmpeg_params = ['-crf', str(crf), '-g', str(frameint), '-pix_fmt', 'yuv420p', '-profile' ,'baseline'])
            """
            sys.stdout.flush()
            clip = None

            # Destroy the temporary directory
            shutil.rmtree(tmp)
            if self.copy_tmp is not None:
                shutil.rmtree(self.copy_tmp)