Skip to content

Instantly share code, notes, and snippets.

@rubo77
Last active November 28, 2020 23:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rubo77/164e671f82f335943ab936e0ba715907 to your computer and use it in GitHub Desktop.
Save rubo77/164e671f82f335943ab936e0ba715907 to your computer and use it in GitHub Desktop.
converts a jpeg file with a planet on black background to a transparent png
#!/usr/bin/python3
# converts a jpeg file with a planet on black background to a transparent png
# like this imagemagick function does:
# for i in planet_*.jpg; do nr=$(echo ${i/planet_/}|sed s/.jpg//g|xargs); convert $i -fuzz 1% -transparent black trans/planet_${nr}.png; done
# but the python script will create them without arkifacts
# needs
# sudo apt install python3-opencv python3-sklearn python3-skimage
# make sure, you created the subfolders thresh/, circle/, mask/, transparent/ and crop/
# mkdir thresh circle mask transparent crop
# call with
# for i in planet_*.jpg; do nr=$(echo ${i/planet_/}|sed s/.jpg//g|xargs); python planet2png.py -i $i -o planet_${nr}.png; done
import cv2
import numpy as np
import sys, getopt
import skimage.exposure
def main(argv):
inputfile = ''
outputfile = ''
try:
opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
except getopt.GetoptError:
print ('planet2png.py -i <inputfile> -o <outputfile>')
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print ('planet2png.py -i <inputfile> -o <outputfile>')
sys.exit()
elif opt in ("-i", "--ifile"):
inputfile = arg
elif opt in ("-o", "--ofile"):
outputfile = arg
if inputfile == '':
print ("missing inputfile")
sys.exit()
if outputfile == '':
print ("missing outputfile")
sys.exit()
print ("crop",inputfile)
# read image
img = cv2.imread(inputfile)
h, w, c = img.shape
# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# get contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
# get enclosing circle
center, radius = cv2.minEnclosingCircle(big_contour)
cx = int(round(center[0]))
cy = int(round(center[1]))
rr = int(round(radius))
# draw outline circle over input
circle = img.copy()
cv2.circle(circle, (cx,cy), rr, (0, 0, 255), 1)
# draw white filled circle on black background as mask
mask = np.full((h,w), 0, dtype=np.uint8)
cv2.circle(mask, (cx,cy), rr, 255, -1)
# antialias
blur = cv2.GaussianBlur(mask, (0,0), sigmaX=1, sigmaY=1, borderType = cv2.BORDER_DEFAULT)
mask = skimage.exposure.rescale_intensity(blur, in_range=(127,255), out_range=(0,255))
# put mask into alpha channel to make outside transparent
imgT = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
imgT[:,:,3] = mask
# crop the image
ulx = int(cx-rr+0.5)
uly = int(cy-rr+0.5)
brx = int(cx+rr+1)
bry = int(cy+rr+1)
print(ulx,brx,uly,bry)
crop = imgT[uly:bry, ulx:brx]
# write result to disk
#cv2.imwrite("thresh/"+outputfile, thresh)
#cv2.imwrite("circle/"+outputfile, circle)
#cv2.imwrite("mask/"+outputfile, mask)
cv2.imwrite("transparent/"+outputfile, imgT)
cv2.imwrite("crop/"+outputfile, crop)
# display it
#cv2.imshow("thresh", thresh)
#cv2.imshow("circle", circle)
#cv2.imshow("mask", mask)
#cv2.waitKey(0)
if __name__ == "__main__":
main(sys.argv[1:])
@rubo77
Copy link
Author

rubo77 commented Nov 28, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment