Last active
February 12, 2026 16:56
-
-
Save possan/15b45a13d640608d90dbb643ef394025 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import time | |
| import cv2 | |
| # | |
| # Terribly slow converter from video to proprietary undocumented hologram file format. | |
| # | |
| # Input file, square video in any format opencv can read, recommended > 256x256. | |
| # | |
| # Installation: | |
| # python -m venv pyenv | |
| # . pyenvbin/activate | |
| # pip3 install opencv-python | |
| # python3 testvideo2.py | |
| # | |
| MODEL_ID = 224 | |
| LINE_PIXEL_NUM = 112 | |
| ANGLE_NUM = 450 | |
| FRAMESKIP = 1 | |
| def chunks(lst, n): | |
| """Yield successive n-sized chunks from lst.""" | |
| for i in range(0, len(lst), n): | |
| yield lst[i:i + n] | |
| def writeHeaders(f, numframes): | |
| arr = [] | |
| # Header | |
| for k in range(4096): | |
| arr.append(ord('h')) | |
| arr[0] = MODEL_ID | |
| arr[1] = 0 | |
| arr[2] = 0 | |
| arr[3] = 1 if numframes > 0 else 60 # framerate mayhaps? | |
| arr[4] = MODEL_ID | |
| # Random encryption thing, 0 = 0x61 | |
| arr[888] = 0 | |
| for k in range(0x61 * 4): | |
| arr.append(ord('e')) | |
| f.write(bytearray(arr)) | |
| def bitArrayToByte(bits): | |
| bitsstr = ''.join(map(lambda bit: str(bit), bits)) | |
| return int(bitsstr, 2) | |
| # This is the slow part, converting the colors to individual bitmasks | |
| def writeFrame(f, img): | |
| arr = [] | |
| height, width, channels = img.shape | |
| for r in range(height): | |
| for bp in range(6): | |
| bpb = [] | |
| bpv = 1 << (5 - bp) | |
| for c in range(width): | |
| cb, cg, cr = img[r, c] | |
| bpb.append(1 if ((cb >> 2) & bpv) == bpv else 0) # blue bit | |
| bpb.append(1 if ((cg >> 2) & bpv) == bpv else 0) # green bit | |
| bpb.append(1 if ((cr >> 2) & bpv) == bpv else 0) # red bit | |
| bytechunks = list(map(bitArrayToByte, list(chunks(bpb, 8)))) | |
| arr += bytechunks | |
| # Pad frame | |
| pad = 114688 - len(arr) | |
| for k in range(pad): | |
| arr.append(0) | |
| f.write(bytearray(arr)) | |
| def processFrame(cap, img, f, idx): | |
| t0 = time.time() | |
| height, width, channels = img.shape | |
| print( "img size: %d x %d x %d channels" % (width, height, channels)) | |
| print (img[int(width/2), int(height/2), 0]) #B Channel Value | |
| # if idx == 0: | |
| # cv2.imshow("input", img) | |
| squaresize = min(width, height) | |
| ox = int((width - squaresize) / 2) | |
| oy = int((height - squaresize) / 2) | |
| print ("Square size: %d (offset %d, %d)" % (squaresize, ox, oy)) | |
| cropped_image = img[oy:oy+squaresize, ox:ox+squaresize] | |
| cropped_image = cv2.flip(cropped_image, 0) | |
| t1 = time.time() | |
| polar = cv2.linearPolar(cropped_image, (squaresize/2, squaresize/2), squaresize/2, cv2.WARP_FILL_OUTLIERS) | |
| output = cv2.resize(polar, (112, 450)); | |
| output = cv2.flip(output, 1) | |
| t2 = time.time() | |
| # if idx == 0: | |
| # cv2.imshow("output", output) | |
| # cv2.waitKey(0) | |
| writeFrame(f, output) | |
| t3 = time.time() | |
| print("timing: %f, %f, %f" % (t1 - t0, t2 - t1, t3 - t2)) | |
| def processVideo(infn, outfn): | |
| f = open(outfn, 'wb') | |
| cap = cv2.VideoCapture(infn) | |
| totalFrames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) | |
| print ("Total frames: %d" % totalFrames) | |
| framesToWrite = int(totalFrames / FRAMESKIP) | |
| writeHeaders(f, framesToWrite) | |
| # res, frame = cap.read() | |
| # processFrame(cap, frame, f) | |
| for fr in range(framesToWrite): | |
| print ("Processing frame %d / %d" % (fr, framesToWrite)) | |
| res, frame = cap.read() | |
| processFrame(cap, frame, f, fr) | |
| # while True: | |
| # ch = 0xFF & cv2.waitKey(1) | |
| # if ch == 27: | |
| # break | |
| f.close() | |
| # cv2.destroyAllWindows() | |
| # | |
| # Start conversion by specifying input and output paths | |
| # | |
| processVideo('video/yodaspin[0001-0100].mp4', 'temp/yodaspin.bin') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment