def save_video_thumbnail(source, output): """Saves thumbnail of the given video under the given name""" player = MediaPlayer(source, ff_opts={'ss': 1.0}) frame, val = None, None while not frame: frame, val = player.get_frame(force_refresh=True) player.close_player() if val == 'eof': return None elif frame is None: return None else: img = frame[0] pixel_format = img.get_pixel_format() img_size = img.get_size() thumb_size = 256, int(img_size[1] * 256 / img_size[0]) codec = 'tiff' output_format = get_supported_pixfmts(codec, pixel_format)[0] #resize and convert into the best pixel format sws = SWScale(img_size[0], img_size[1], pixel_format, thumb_size[0], thumb_size[1], output_format) thumbnail = sws.scale(img) streams = [{ 'pix_fmt_in': output_format, 'width_in': thumb_size[0], 'height_in': thumb_size[1], 'codec': codec, 'frame_rate': (30, 1) }] writer = MediaWriter(output, streams, lib_opts={'compression_algo': 'lzw'}) writer.write_frame(img=thumbnail, pts=0, stream=0) writer.close()
def save_image(fname, img, codec='bmp', pix_fmt='', lib_opts={}): """Saves the given image to disk in the format requested. :param fname: The filename where to save the image. :param img: The :class:`ffpyplayer.pic.Image` to save. :param codec: The codec to pass to :class:`ffpyplayer.writer.MediaWriter` that determines the image type. Defaults to 'bmp'. :param pix_fmt: The pixel format into which to convert the image before saving. If empty, the original pixel format is used. If the codec doesn't support the image format, we first convert it to the closest supported format. :param lib_opts: Any additional `lib_opts` options to pass to :class:`ffpyplayer.writer.MediaWriter`. :return: The estimated size of the image on disk. """ fmt = img.get_pixel_format() w, h = img.get_size() if not codec: codec = get_format_codec(fname) ofmt = get_supported_pixfmts(codec, fmt)[0] else: ofmt = get_supported_pixfmts(codec, pix_fmt or fmt)[0] if ofmt != fmt: sws = SWScale(w, h, fmt, ofmt=ofmt) img = sws.scale(img) fmt = ofmt out_opts = {'pix_fmt_in': fmt, 'width_in': w, 'height_in': h, 'frame_rate': (30, 1), 'codec': codec} writer = MediaWriter(fname, [out_opts], lib_opts=lib_opts) size = writer.write_frame(img=img, pts=0, stream=0) writer.close() return size
def get_converted_frame(self): if self.first_frame: frame = self.first_frame self.first_frame = None else: self.player.set_pause(False) frame = None while not frame: frame, value = self.player.get_frame(force_refresh=False) if value == 'eof': return None self.player.set_pause(True) self.frame_number = self.frame_number + 1 if self.max_frames: if self.frame_number > self.max_frames: return None frame_image = frame[0] frame_size = frame_image.get_size() frame_converter = SWScale(frame_size[0], frame_size[1], frame_image.get_pixel_format(), ofmt='rgb24') new_frame = frame_converter.scale(frame_image) image_data = bytes(new_frame.to_bytearray()[0]) image = Image.frombuffer(mode='RGB', size=(frame_size[0], frame_size[1]), data=image_data, decoder_name='raw') #for some reason, video frames are read upside-down? fix it here... image = image.transpose(PIL.Image.FLIP_TOP_BOTTOM) if image.mode != 'RGB': image = image.convert('RGB') image = self.adjust_image(image, preview=False) return [image, frame[1]]
def load(self, filename): try: loader = ffImageLoader(filename) except: Logger.warning('Image: Unable to load image <%s>' % filename) raise # update internals self.filename = filename images = [] while True: frame, t = loader.next_frame() if frame is None: break images.append(frame) if not len(images): raise Exception('No image found in {}'.format(filename)) w, h = images[0].get_size() ifmt = images[0].get_pixel_format() if ifmt != 'rgba' and ifmt != 'rgb24': fmt = 'rgba' sws = SWScale(w, h, ifmt, ofmt=fmt) for i, image in enumerate(images): images[i] = sws.scale(image) else: fmt = ifmt if ifmt == 'rgba' else 'rgb' return [ ImageData(w, h, fmt, img.to_memoryview()[0], source_image=img) for img in images ]
def load(self, filename): try: loader = ffImageLoader(filename) except: Logger.warning('Image: Unable to load image <%s>' % filename) raise # update internals self.filename = filename images = [] while True: frame, t = loader.next_frame() if frame is None: break images.append(frame) if not len(images): raise Exception('No image found in {}'.format(filename)) w, h = images[0].get_size() ifmt = images[0].get_pixel_format() if ifmt != 'rgba' and ifmt != 'rgb24': fmt = 'rgba' sws = SWScale(w, h, ifmt, ofmt=fmt) for i, image in enumerate(images): images[i] = sws.scale(image) else: fmt = ifmt if ifmt == 'rgba' else 'rgb' return [ImageData(w, h, fmt, img.to_memoryview()[0], source_image=img) for img in images]
def process_in_kivy_thread(self, *largs): """Processes messages from the client in the kivy thread. """ while self.to_kivy_queue is not None: try: msg, value = self.to_kivy_queue.get(block=False) if msg == 'exception': e, exec_info = value cpl_media.error_callback(e, exc_info=exec_info) elif msg == 'exception_exit': e, exec_info = value cpl_media.error_callback(e, exc_info=exec_info) self.stop_all() if self.play_state != 'none': self.complete_stop() elif msg == 'started_recording': if self.play_state == 'starting': self.ts_play = self._ivl_start = clock() self._frame_count = 0 self.metadata_play_used = VideoMetadata(*value) self.complete_start() elif msg == 'stopped_recording': self.stop() elif msg == 'stopped_playing': self.complete_stop() elif msg == 'image': if self.play_state != 'playing': continue t = clock() if t - self._ivl_start >= 1.: self.real_rate = self._frame_count / (t - self._ivl_start) self._frame_count = 0 self._ivl_start = t self._frame_count += 1 self.frames_played += 1 plane_buffers, pix_fmt, size, linesize, metadata = value sws = SWScale(*size, pix_fmt, ofmt=pix_fmt) img = Image(plane_buffers=plane_buffers, pix_fmt=pix_fmt, size=size, linesize=linesize) self.process_frame(sws.scale(img), metadata) else: print('Got unknown RemoteVideoPlayer message', msg, value) except Empty: break
def test_pic(): from ffpyplayer.pic import SWScale size = w, h = 500, 100 img = create_image(size) assert not img.is_ref() assert img.get_size() == (w, h) sws = SWScale(w, h, img.get_pixel_format(), ofmt='yuv420p') img2 = sws.scale(img) assert img2.get_pixel_format() == 'yuv420p' planes = img2.to_bytearray() assert list(map(len, planes)) == [w * h, w * h / 4, w * h / 4, 0]
def test_pic(self): from ffpyplayer.pic import Image, SWScale size = w, h = 500, 100 img = self.create_image(size) self.assertFalse(img.is_ref()) self.assertEqual(img.get_size(), (w, h)) sws = SWScale(w, h, img.get_pixel_format(), ofmt='yuv420p') img2 = sws.scale(img) self.assertEqual(img2.get_pixel_format(), 'yuv420p') planes = img2.to_bytearray() self.assertEqual(list(map(len, planes)), [w * h, w * h / 4, w * h / 4, 0])
def process_in_kivy_thread(self, *largs): while self.to_kivy_queue is not None: try: msg, value = self.to_kivy_queue.get(block=False) if msg == 'exception': e, exec_info = value App.get_running_app().handle_exception( e, exc_info=exec_info) self.stop_listener() elif msg == 'server_exception': e, exec_info = value App.get_running_app().handle_exception( e, exc_info=exec_info) elif msg == 'track_cam_setting': player = knspace.player if player is not None: player.bind_pt_remote_setting(value) elif msg == 'get_cam_settings': player = knspace.player if player is not None: self.send_cam_settings('cam_settings', player.get_valid_pt_settings()) elif msg == 'set_cam_setting': player = knspace.player if player is not None: player.change_pt_setting_opt(*value) elif msg == 'reload_cam_setting': player = knspace.player if player is not None: player.reload_pt_setting_opt(value) elif msg == 'remote_image': remote_player = App.get_running_app().remote_player plane_buffers, pix_fmt, size, linesize = value sws = SWScale(*size, pix_fmt, ofmt=pix_fmt) img = Image( plane_buffers=plane_buffers, pix_fmt=pix_fmt, size=size, linesize=linesize) remote_player.last_image = sws.scale(img) remote_player.display_trigger() else: print('got', msg, value) except Empty: break
def play(screen, asciiToNum, videoPath): player = MediaPlayer(videoPath) screen.nodelay(True) while 1: frame, val = player.get_frame() if val == 'eof': break elif frame is None: time.sleep(0.01) else: time_bf = time.time() c = screen.getch() if c == ord('q'): break img, t = frame w, h = img.get_size() sws = SWScale(w, h, img.get_pixel_format(), ofmt='yuv420p', ow=w // 8, oh=h // 8) img_scaled = sws.scale(img) frame_scaled = np.uint8( np.array(list(img_scaled.to_bytearray()[0]))).reshape( h // 8, w // 8) transformedAscii = transform(frame_scaled, asciiToNum) s = arrayToString(transformedAscii) time_af = time.time() screen.erase() screen.addstr(s) screen.addstr(str(t)) screen.refresh() time.sleep(0 if 0 > val - (time_af - time_bf) else val - (time_af - time_bf)) player.close_player()
def predict_image(self, image): fmt = image.get_pixel_format() scaler = self.image_scaler if fmt != 'gray': if scaler is None or fmt != self.last_img_fmt: scaler = self.image_scaler = SWScale(*image.get_size(), fmt, ofmt='gray') self.last_img_fmt = fmt image = scaler.scale(image) buffer = np.frombuffer(image.to_bytearray()[0], dtype=np.uint8) w, h = image.get_size() buffer = np.reshape(buffer, (h, w)) #cv2.imshow('Video', buffer) buffer = resize(buffer, (100, 200)) buffer = buffer.flatten() buffer = buffer[np.newaxis, :] pred = self.clf.predict(buffer)[0] return buffer, pred
def _show_image(config, img, scale=None, translation=None, rotation=None, transform_matrix=None): from kivy.graphics.texture import Texture from kivy.graphics.fbo import Fbo from kivy.graphics import (Mesh, StencilPush, StencilUse, StencilUnUse, StencilPop, Rectangle, Color) from kivy.graphics.context_instructions import (PushMatrix, PopMatrix, Rotate, Translate, Scale, MatrixInstruction, BindTexture) from kivy.graphics.transformation import Matrix img_fmt = img.get_pixel_format() img_w, img_h = img.get_size() size = config['orig_size'] pos = config['pos'] canvas = config['canvas'] if img_fmt not in ('yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra'): ofmt = get_best_pix_fmt( img_fmt, ('yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra')) swscale = SWScale(iw=img_w, ih=img_h, ifmt=img_fmt, ow=0, oh=0, ofmt=ofmt) img = swscale.scale(img) img_fmt = img.get_pixel_format() kivy_ofmt = { 'yuv420p': 'yuv420p', 'rgba': 'rgba', 'rgb24': 'rgb', 'gray': 'luminance', 'bgr24': 'bgr', 'bgra': 'bgra' }[img_fmt] if kivy_ofmt == 'yuv420p': w2 = int(img_w / 2) h2 = int(img_h / 2) tex_y = Texture.create(size=(img_w, img_h), colorfmt='luminance') tex_u = Texture.create(size=(w2, h2), colorfmt='luminance') tex_v = Texture.create(size=(w2, h2), colorfmt='luminance') with canvas: fbo = Fbo(size=(img_w, img_h)) with fbo: BindTexture(texture=tex_u, index=1) BindTexture(texture=tex_v, index=2) Rectangle(size=fbo.size, texture=tex_y) fbo.shader.fs = CeedDataReader._YUV_RGB_FS fbo['tex_y'] = 0 fbo['tex_u'] = 1 fbo['tex_v'] = 2 tex = fbo.texture dy, du, dv, _ = img.to_memoryview() tex_y.blit_buffer(dy, colorfmt='luminance') tex_u.blit_buffer(du, colorfmt='luminance') tex_v.blit_buffer(dv, colorfmt='luminance') else: tex = Texture.create(size=(img_w, img_h), colorfmt=kivy_ofmt) tex.blit_buffer(img.to_memoryview()[0], colorfmt=kivy_ofmt) tex.flip_vertical() with canvas: StencilPush() Rectangle(pos=pos, size=size) StencilUse() PushMatrix() center = pos[0] + size[0] / 2, pos[1] + size[1] / 2 if rotation: Rotate(angle=rotation, axis=(0, 0, 1), origin=center) if scale: Scale(scale, scale, 1, origin=center) if translation: Translate(*translation) if transform_matrix is not None: mat = Matrix() mat.set(array=transform_matrix) m = MatrixInstruction() m.matrix = mat Rectangle(size=(img_w, img_h), texture=tex, pos=pos) PopMatrix() StencilUnUse() Rectangle(pos=pos, size=size) StencilPop()
def update_img(self, img, force=False): ''' Updates the screen with a new image. :Parameters: `img`: :class:`~ffpyplayer.pic.Image` instance The image to be displayed. ''' from ffpyplayer.tools import get_best_pix_fmt from ffpyplayer.pic import SWScale if img is None: return img_fmt = img.get_pixel_format() self.image_size = img_w, img_h = img.get_size() update = force if self._iw != img_w or self._ih != img_h: update = True if img_fmt not in ('yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra'): swscale = self._swscale if img_fmt != self._sw_src_fmt or swscale is None or update: ofmt = get_best_pix_fmt( img_fmt, ( 'yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra')) self._swscale = swscale = SWScale( iw=img_w, ih=img_h, ifmt=img_fmt, ow=0, oh=0, ofmt=ofmt) self._sw_src_fmt = img_fmt img = swscale.scale(img) img_fmt = img.get_pixel_format() w, h = self.available_size or self.size if (not w) or not h: self.img = img return if self._fmt != img_fmt: self._fmt = img_fmt self._kivy_ofmt = { 'yuv420p': 'yuv420p', 'rgba': 'rgba', 'rgb24': 'rgb', 'gray': 'luminance', 'bgr24': 'bgr', 'bgra': 'bgra'}[img_fmt] update = True if update or w != self._last_w or h != self._last_h or \ self.rotation != self._last_rotation: if self.scale_to_image: rotation = self.rotation rot = self.rotation * math.pi / 180 rot_w = abs(img_w * math.cos(rot)) + abs(img_h * math.sin(rot)) rot_h = abs(img_h * math.cos(rot)) + abs(img_w * math.sin(rot)) scalew, scaleh = w / rot_w, h / rot_h scale = min(min(scalew, scaleh), 1) self.transform = Matrix() self.rotation = rotation self.apply_transform(Matrix().scale(scale, scale, 1), post_multiply=True) self.pos = 0, 0 self._iw, self._ih = img_w, img_h self._last_h = h self._last_w = w self._last_rotation = self.rotation self.img = img kivy_ofmt = self._kivy_ofmt if update: self.canvas.remove_group(str(self) + 'image_display') if kivy_ofmt == 'yuv420p': w2 = int(img_w / 2) h2 = int(img_h / 2) self._tex_y = Texture.create(size=(img_w, img_h), colorfmt='luminance') self._tex_u = Texture.create(size=(w2, h2), colorfmt='luminance') self._tex_v = Texture.create(size=(w2, h2), colorfmt='luminance') with self.canvas: self._fbo = fbo = Fbo(size=(img_w, img_h), group=str(self) + 'image_display') with fbo: BindTexture(texture=self._tex_u, index=1) BindTexture(texture=self._tex_v, index=2) Rectangle(size=fbo.size, texture=self._tex_y) fbo.shader.fs = BufferImage._YUV_RGB_FS fbo['tex_y'] = 0 fbo['tex_u'] = 1 fbo['tex_v'] = 2 tex = self.img_texture = fbo.texture fbo.add_reload_observer(self.reload_buffer) else: tex = self.img_texture = Texture.create( size=(img_w, img_h), colorfmt=kivy_ofmt) tex.add_reload_observer(self.reload_buffer) tex.flip_vertical() if self.flip: tex.flip_horizontal() self.texture_size = img_w, img_h if kivy_ofmt == 'yuv420p': dy, du, dv, _ = img.to_memoryview() self._tex_y.blit_buffer(dy, colorfmt='luminance') self._tex_u.blit_buffer(du, colorfmt='luminance') self._tex_v.blit_buffer(dv, colorfmt='luminance') self._fbo.ask_update() self._fbo.draw() else: self.img_texture.blit_buffer(img.to_memoryview()[0], colorfmt=kivy_ofmt) self.canvas.ask_update()
#fmt = 'rgb565le' buffer_size = 3686400 # get form fb_fix_screeninfo.smem_len h = buffer_size / line_length codec = 'png' file = open(sys.argv[1], "rb") buf = bytearray(file.read()) img = Image(plane_buffers=[buf], pix_fmt=fmt, size=(w, h)) # make sure the output codec supports the input pixel format type # otherwise, convert it to the best pixel format ofmt = get_supported_pixfmts(codec, fmt)[0] if ofmt != fmt: sws = SWScale(w, h, fmt, ofmt=ofmt) img = sws.scale(img) fmt = ofmt out_opts = { 'pix_fmt_in': fmt, 'width_in': w, 'height_in': h, 'frame_rate': (30, 1), 'codec': codec } writer = MediaWriter('output.' + codec, [out_opts]) writer.write_frame(img=img, pts=0, stream=0) writer.close() file.close()
def reload_edit_image(self): """Regenerate the edit preview image.""" if self.video: if not self.player: return location = self.length * self.position frame = self.seek_player(location) frame = frame[0] frame_size = frame.get_size() pixel_format = frame.get_pixel_format() frame_converter = SWScale(frame_size[0], frame_size[1], pixel_format, ofmt='rgb24') new_frame = frame_converter.scale(frame) image_data = bytes(new_frame.to_bytearray()[0]) original_image = Image.frombuffer(mode='RGB', size=(frame_size[0], frame_size[1]), data=image_data, decoder_name='raw') #for some reason, video frames are read upside-down? fix it here... original_image = original_image.transpose( PIL.Image.FLIP_TOP_BOTTOM) self.original_width = original_image.size[0] self.original_height = original_image.size[1] self.original_image = original_image image = original_image.copy() else: original_image = Image.open(self.source) try: self.exif = original_image.info.get('exif', b'') except: self.exif = '' if self.angle != 0: if self.angle == 90: original_image = original_image.transpose( PIL.Image.ROTATE_90) if self.angle == 180: original_image = original_image.transpose( PIL.Image.ROTATE_180) if self.angle == 270: original_image = original_image.transpose( PIL.Image.ROTATE_270) self.original_width = original_image.size[0] self.original_height = original_image.size[1] image = original_image.copy() self.original_image = original_image.copy() original_image.close() image_width = Window.width * .75 width = int(image_width) height = int(image_width * (image.size[1] / image.size[0])) if width < 10: width = 10 if height < 10: height = 10 image = image.resize((width, height)) if image.mode != 'RGB': image = image.convert('RGB') self.size_multiple = self.original_width / image.size[0] self.edit_image = image Clock.schedule_once( self.update_histogram ) #Need to delay this because kivy will mess up the drawing of it on first load.
#trainer = Trainer(train_path="data/trainer_touch/", test_path="data/tester_touch/") #trainer.train() print("loading classifier..") clf = load('filename.joblib') print("start video...") while True: frame, val = player.get_frame() if val == 'eof': break elif frame is None: time.sleep(0.01) else: img, t = frame fmt = img.get_pixel_format() scaler = SWScale(*img.get_size(), fmt, ofmt='gray') image = scaler.scale(img) #print(val, t, img.get_pixel_format(), img.get_buffer_size()) buffer = np.frombuffer(image.to_bytearray()[0], dtype=np.uint8) w, h = image.get_size() buffer = np.reshape(buffer, (h, w)) #buffer = resize(buffer, (100, 200)) #bu, pred = trainer.predict_image(img) bu = resize(buffer, (100, 200), mode='constant') bu = bu.flatten() bu = bu[np.newaxis, :] pred = clf.predict(bu)[0] #pred = 1
def _show_image( config, img, scale=None, translation=None, rotation=None, transform_matrix=None): from kivy.graphics.texture import Texture from kivy.graphics.fbo import Fbo from kivy.graphics import ( Mesh, StencilPush, StencilUse, StencilUnUse, StencilPop, Rectangle, Color) from kivy.graphics.context_instructions import ( PushMatrix, PopMatrix, Rotate, Translate, Scale, MatrixInstruction, BindTexture) from kivy.graphics.transformation import Matrix img_fmt = img.get_pixel_format() img_w, img_h = img.get_size() size = config['orig_size'] pos = config['pos'] canvas = config['canvas'] if img_fmt not in ('yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra'): ofmt = get_best_pix_fmt( img_fmt, ('yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra')) swscale = SWScale( iw=img_w, ih=img_h, ifmt=img_fmt, ow=0, oh=0, ofmt=ofmt) img = swscale.scale(img) img_fmt = img.get_pixel_format() kivy_ofmt = { 'yuv420p': 'yuv420p', 'rgba': 'rgba', 'rgb24': 'rgb', 'gray': 'luminance', 'bgr24': 'bgr', 'bgra': 'bgra'}[img_fmt] if kivy_ofmt == 'yuv420p': w2 = int(img_w / 2) h2 = int(img_h / 2) tex_y = Texture.create(size=(img_w, img_h), colorfmt='luminance') tex_u = Texture.create(size=(w2, h2), colorfmt='luminance') tex_v = Texture.create(size=(w2, h2), colorfmt='luminance') with canvas: fbo = Fbo(size=(img_w, img_h)) with fbo: BindTexture(texture=tex_u, index=1) BindTexture(texture=tex_v, index=2) Rectangle(size=fbo.size, texture=tex_y) fbo.shader.fs = CeedDataReader._YUV_RGB_FS fbo['tex_y'] = 0 fbo['tex_u'] = 1 fbo['tex_v'] = 2 tex = fbo.texture dy, du, dv, _ = img.to_memoryview() tex_y.blit_buffer(dy, colorfmt='luminance') tex_u.blit_buffer(du, colorfmt='luminance') tex_v.blit_buffer(dv, colorfmt='luminance') else: tex = Texture.create(size=(img_w, img_h), colorfmt=kivy_ofmt) tex.blit_buffer(img.to_memoryview()[0], colorfmt=kivy_ofmt) tex.flip_vertical() with canvas: StencilPush() Rectangle(pos=pos, size=size) StencilUse() PushMatrix() center = pos[0] + size[0] / 2, pos[1] + size[1] / 2 if rotation: Rotate(angle=rotation, axis=(0, 0, 1), origin=center) if scale: Scale(scale, scale, 1, origin=center) if translation: Translate(*translation) if transform_matrix is not None: mat = Matrix() mat.set(array=transform_matrix) m = MatrixInstruction() m.matrix = mat Rectangle(size=(img_w, img_h), texture=tex, pos=pos) PopMatrix() StencilUnUse() Rectangle(pos=pos, size=size) StencilPop()