Loading jp4-to-png.py +8 −72 Original line number Diff line number Diff line #!/usr/bin/env python3 import jp4 from jp4_composite import JP4_C #import cv2 import numpy as np import sys from PIL import Image, ImageOps import os try: filename = sys.argv[1] except IndexError: filename = "test.jp4" img = jp4.JP4(filename) # print exif img = JP4_C(filename) #print(img.exif.toString()) # deblock if JP4 (auto read from exif) skip if other #print(img.exif.data['Model']) img.deblock() img.demosaic_bilinear() img.saturation() subs = img.extract_subframes() I = img.image[...,[2,1,0]].astype(np.uint8) res = Image.fromarray(I) #res.save("result.png") # also works #res.save("result.jpeg") # for Eyesis4pi exif = img.exif mn = exif.MakerNote #print(exif.MakerNote) # common # WOI_WIDTH # FLIPH # FLIPV # PORTRAIT # COMPOSITE # individual # HEIGHTx, 1..3 # FLIPHx, 1..3 # FLIPVx, 1..3 # BLANKx, only 1 and 2 if mn['COMPOSITE']: W = mn['WOI_WIDTH'] H = mn['WOI_HEIGHT'] FH = mn['FLIPH'] FV = mn['FLIPV'] #if FV: # I = v_offset = 0 for i in range(1,4): try: height = mn['HEIGHT'+str(i)] #fliph = mn['FLIPH'+str(i)] flipv = mn['FLIPV'+str(i)] except KeyError: # break for '_9' break try: blank = mn['BLANK'+str(i)] except KeyError: blank = 0 crop = res.crop((0,v_offset,W,v_offset+height)) if flipv: crop = ImageOps.flip(crop) # if eyesis4pi, 1&2 - rotate 90CW, 3 - 90CCW if i<3: crop = crop.rotate(-90,expand=1) else: crop = crop.rotate(90,expand=1) crop.save("result_"+str(i)+".jpeg") v_offset += height + blank for i in range(len(subs)): #subs[i].save(os.path.join("../res",img.basename+"_"+str(img.subnames[i])+".png")) subs[i].save(os.path.join("../res",img.basename+"_"+str(img.subnames[i])+".jpeg")) jp4.py +6 −6 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ def get_exif(filename): # exif.MakerNote - parsed as dict return exif # clear from code # add upper row def naur(a): b0 = a[0] b0 = np.reshape(b0,(1,b0.shape[0])) Loading @@ -36,7 +36,7 @@ def naur(a): b = np.concatenate((b0,b),axis=0) return b # clear from code # add bottom row def nabr(a): b0 = a[-1] b0 = np.reshape(b0,(1,b0.shape[0])) Loading @@ -44,7 +44,7 @@ def nabr(a): b = np.concatenate((b,b0),axis=0) return b # clear from code # add left column def nalc(a): b0 = a[::,0] b0 = np.reshape(b0,(b0.shape[0],1)) Loading @@ -52,7 +52,7 @@ def nalc(a): b = np.concatenate((b0,b),axis=1) return b # clear from code # add right column def narc(a): b0 = a[::,-1] b0 = np.reshape(b0,(b0.shape[0],1)) Loading Loading @@ -126,7 +126,7 @@ class JP4: im_arr = np.fromstring(im.tobytes(), dtype=np.uint8) im_arr = im_arr.reshape((im.size[1], im.size[0])) print(im_arr.shape) #print(im_arr.shape) self.image = im_arr self.h, self.w = self.image.shape Loading jp4_batch_convert.py 0 → 100644 +39 −0 Original line number Diff line number Diff line #!/usr/bin/env python3 from jp4_composite import JP4_C #import cv2 import numpy as np import sys from PIL import Image, ImageOps import os try: src = sys.argv[1] except IndexError: src = "." try: dst = sys.argv[2] except IndexError: dst = "." lst = os.listdir(src) lst.sort() for f in lst: path = os.path.join(src,f) if os.path.isfile(path): print("Converting "+f) img = JP4_C(path) #print(img.exif.toString()) #print(img.exif.data['Model']) img.deblock() img.demosaic_bilinear() img.saturation() subs = img.extract_subframes() for i in range(len(subs)): #subs[i].save(os.path.join("../res",img.basename+"_"+str(img.subnames[i])+".png")) subs[i].save(os.path.join(dst,img.basename+"_"+str(img.subnames[i])+".jpeg")) jp4_composite.py 0 → 100644 +120 −0 Original line number Diff line number Diff line import re import os from PIL import Image, ImageOps import numpy as np from jp4 import JP4 class JP4_C(JP4): def __init__(self,filename): JP4.__init__(self,filename) self.filename = filename # filename includes path # if multiple cameras the files will be indexed: basename_{i}.ext self.model = "Unknown" self.basename = self.__basename(filename) self.subnames = self.__subnames() # extract basename if part of indexed set def __basename(self,s): m = re.search('_\d+\.',s) # likely if m: basename = os.path.basename(s[:m.start(0)]) # unlikely else: basename = os.path.splittext(os.path.basename(s))[0] return basename # based on application name def __subnames(self): subnames = [0,1,2] # model tag has camera name and its channel model = self.exif.data['Model'] m = re.search('^EYESIS',model) if m: self.model = "EYESIS" m = re.search('CHN(\d+)$',model) if m: chn = int(m.group(1)) if chn==109: subnames = [24,25] else: subnames = [chn-101,chn-101+8,chn-101+16] return subnames # based on exif MakeNote # return array of subframes - flipped and rotated def extract_subframes(self): # convert to PIL format and reorder # TODO: change stacking in jp4.py to RGB I = Image.fromarray(self.image[...,[2,1,0]].astype(np.uint8)) exif = self.exif mn = exif.MakerNote subframes = [] W = mn['WOI_WIDTH'] H = mn['WOI_HEIGHT'] FH = mn['FLIPH'] FV = mn['FLIPV'] v_offset = 0 for i in range(1,4): try: height = mn['HEIGHT'+str(i)] #fliph = mn['FLIPH'+str(i)] flipv = mn['FLIPV'+str(i)] except KeyError: # break for '_9' break # actual break for '_9' if height==0: break try: blank = mn['BLANK'+str(i)] except KeyError: blank = 0 crop = I.crop((0,v_offset,W,v_offset+height)) if flipv: crop = ImageOps.flip(crop) # if eyesis4pi, 1&2 - rotate 90CW, 3 - 90CCW if i<3: # special case if self.model=="EYESIS" and self.subnames[i-1]==25: crop = crop.rotate(90,expand=1) else: crop = crop.rotate(-90,expand=1) else: crop = crop.rotate(90,expand=1) subframes.append(crop) #crop.save("result_"+str(i)+".jpeg") v_offset += height + blank return subframes Loading
jp4-to-png.py +8 −72 Original line number Diff line number Diff line #!/usr/bin/env python3 import jp4 from jp4_composite import JP4_C #import cv2 import numpy as np import sys from PIL import Image, ImageOps import os try: filename = sys.argv[1] except IndexError: filename = "test.jp4" img = jp4.JP4(filename) # print exif img = JP4_C(filename) #print(img.exif.toString()) # deblock if JP4 (auto read from exif) skip if other #print(img.exif.data['Model']) img.deblock() img.demosaic_bilinear() img.saturation() subs = img.extract_subframes() I = img.image[...,[2,1,0]].astype(np.uint8) res = Image.fromarray(I) #res.save("result.png") # also works #res.save("result.jpeg") # for Eyesis4pi exif = img.exif mn = exif.MakerNote #print(exif.MakerNote) # common # WOI_WIDTH # FLIPH # FLIPV # PORTRAIT # COMPOSITE # individual # HEIGHTx, 1..3 # FLIPHx, 1..3 # FLIPVx, 1..3 # BLANKx, only 1 and 2 if mn['COMPOSITE']: W = mn['WOI_WIDTH'] H = mn['WOI_HEIGHT'] FH = mn['FLIPH'] FV = mn['FLIPV'] #if FV: # I = v_offset = 0 for i in range(1,4): try: height = mn['HEIGHT'+str(i)] #fliph = mn['FLIPH'+str(i)] flipv = mn['FLIPV'+str(i)] except KeyError: # break for '_9' break try: blank = mn['BLANK'+str(i)] except KeyError: blank = 0 crop = res.crop((0,v_offset,W,v_offset+height)) if flipv: crop = ImageOps.flip(crop) # if eyesis4pi, 1&2 - rotate 90CW, 3 - 90CCW if i<3: crop = crop.rotate(-90,expand=1) else: crop = crop.rotate(90,expand=1) crop.save("result_"+str(i)+".jpeg") v_offset += height + blank for i in range(len(subs)): #subs[i].save(os.path.join("../res",img.basename+"_"+str(img.subnames[i])+".png")) subs[i].save(os.path.join("../res",img.basename+"_"+str(img.subnames[i])+".jpeg"))
jp4.py +6 −6 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ def get_exif(filename): # exif.MakerNote - parsed as dict return exif # clear from code # add upper row def naur(a): b0 = a[0] b0 = np.reshape(b0,(1,b0.shape[0])) Loading @@ -36,7 +36,7 @@ def naur(a): b = np.concatenate((b0,b),axis=0) return b # clear from code # add bottom row def nabr(a): b0 = a[-1] b0 = np.reshape(b0,(1,b0.shape[0])) Loading @@ -44,7 +44,7 @@ def nabr(a): b = np.concatenate((b,b0),axis=0) return b # clear from code # add left column def nalc(a): b0 = a[::,0] b0 = np.reshape(b0,(b0.shape[0],1)) Loading @@ -52,7 +52,7 @@ def nalc(a): b = np.concatenate((b0,b),axis=1) return b # clear from code # add right column def narc(a): b0 = a[::,-1] b0 = np.reshape(b0,(b0.shape[0],1)) Loading Loading @@ -126,7 +126,7 @@ class JP4: im_arr = np.fromstring(im.tobytes(), dtype=np.uint8) im_arr = im_arr.reshape((im.size[1], im.size[0])) print(im_arr.shape) #print(im_arr.shape) self.image = im_arr self.h, self.w = self.image.shape Loading
jp4_batch_convert.py 0 → 100644 +39 −0 Original line number Diff line number Diff line #!/usr/bin/env python3 from jp4_composite import JP4_C #import cv2 import numpy as np import sys from PIL import Image, ImageOps import os try: src = sys.argv[1] except IndexError: src = "." try: dst = sys.argv[2] except IndexError: dst = "." lst = os.listdir(src) lst.sort() for f in lst: path = os.path.join(src,f) if os.path.isfile(path): print("Converting "+f) img = JP4_C(path) #print(img.exif.toString()) #print(img.exif.data['Model']) img.deblock() img.demosaic_bilinear() img.saturation() subs = img.extract_subframes() for i in range(len(subs)): #subs[i].save(os.path.join("../res",img.basename+"_"+str(img.subnames[i])+".png")) subs[i].save(os.path.join(dst,img.basename+"_"+str(img.subnames[i])+".jpeg"))
jp4_composite.py 0 → 100644 +120 −0 Original line number Diff line number Diff line import re import os from PIL import Image, ImageOps import numpy as np from jp4 import JP4 class JP4_C(JP4): def __init__(self,filename): JP4.__init__(self,filename) self.filename = filename # filename includes path # if multiple cameras the files will be indexed: basename_{i}.ext self.model = "Unknown" self.basename = self.__basename(filename) self.subnames = self.__subnames() # extract basename if part of indexed set def __basename(self,s): m = re.search('_\d+\.',s) # likely if m: basename = os.path.basename(s[:m.start(0)]) # unlikely else: basename = os.path.splittext(os.path.basename(s))[0] return basename # based on application name def __subnames(self): subnames = [0,1,2] # model tag has camera name and its channel model = self.exif.data['Model'] m = re.search('^EYESIS',model) if m: self.model = "EYESIS" m = re.search('CHN(\d+)$',model) if m: chn = int(m.group(1)) if chn==109: subnames = [24,25] else: subnames = [chn-101,chn-101+8,chn-101+16] return subnames # based on exif MakeNote # return array of subframes - flipped and rotated def extract_subframes(self): # convert to PIL format and reorder # TODO: change stacking in jp4.py to RGB I = Image.fromarray(self.image[...,[2,1,0]].astype(np.uint8)) exif = self.exif mn = exif.MakerNote subframes = [] W = mn['WOI_WIDTH'] H = mn['WOI_HEIGHT'] FH = mn['FLIPH'] FV = mn['FLIPV'] v_offset = 0 for i in range(1,4): try: height = mn['HEIGHT'+str(i)] #fliph = mn['FLIPH'+str(i)] flipv = mn['FLIPV'+str(i)] except KeyError: # break for '_9' break # actual break for '_9' if height==0: break try: blank = mn['BLANK'+str(i)] except KeyError: blank = 0 crop = I.crop((0,v_offset,W,v_offset+height)) if flipv: crop = ImageOps.flip(crop) # if eyesis4pi, 1&2 - rotate 90CW, 3 - 90CCW if i<3: # special case if self.model=="EYESIS" and self.subnames[i-1]==25: crop = crop.rotate(90,expand=1) else: crop = crop.rotate(-90,expand=1) else: crop = crop.rotate(90,expand=1) subframes.append(crop) #crop.save("result_"+str(i)+".jpeg") v_offset += height + blank return subframes