Running a Studio on a command line
Tools:
Mutt for email.
Task Warrior for to do.
Time Warrior for time tracking on tasks
CMUS - music player
Vim for text/code editing
Search engines doesn't work
For design(and dev): Sometimes default search engines(google/DDG) doesn't work at all.
For design(and dev) related queries, sometimes default search engines(google/DDG) doesn't work at all.
Now a days I directly go to:
* Hacker News search
* Orielly book search
* Internet archive book/documents search
* Stackexchange(of course)
Better, search what you want on Google;
Tools > select custom time range > Select any time before 2008
* No SEO manipulated pages
* Plain html/text pages
* More often takes you in the right path.
* This won't work in YouTube.(new content creators can't monetise then)
Faster way to do emails
Want to try new way of doing emails, have some time to burn, want to have fun:
Why not try Mutt? It’s been there since 1995
Every one wants to do faster emails now! — but why? that is an altogether different question, as in, why would any one want a lite-help-desk-software for managing emails?
But hey Hey.com[1]
To every one who is eagerly waiting to get an invite from Hey.com
If your question is: How is this problem being solved now? How are power email users managing emails?
Want to try new way of doing emails, have some time to burn, want to have fun:
Why not try Mutt? [2]
It is free under General Public License, been there since 1995.Refer [5][6]
Typical Mutt setup:
Your fav terminal > Mutt > Vim[3] > GnuPG[4]
In a way, it is a faster way to do emails:
* Entirely command line.
* Plain text only
* Key bindings that you can learn and master
* Configure your favourite editor to compose(a good opportunity to learn Vim)
* GPG end-to-end encryption support
Caveats
* Take just minutes to get it up and running, but configuring perfectly will a be work in progress.[4]
* High learning curve, but hey any thing worth doing is.
[1] https://hey.com/
[2] http://www.mutt.org/
[3] https://www.vim.org/
[4] https://gnupg.org/
[5] https://stevelosh.com/blog/2012/10/the-homely-mutt/
[6] https://wiki.archlinux.org/index.php/Mutt
[7] Mutt in action: Video
After thoughts:
Quoting Hey.com from this link:
Either they rely on everyone using the same service/app (good luck converting everyone you email with to use the same setup as you!). Or the emails aren’t really emails, but links to a website where the encryption is then applied. Or you use a clunky external tool to encrypt and decrypt the messages (like PGP). This really only works if you’re willing to give up on email as we commonly understand it. If you absolutely must have end-to-end encrypted email, checkout something like ProtonMail.
This posturing, I don’t understand, Hey.com’s narrative is don’t believe in Google, but believe us, why should anyone? — without end-to-end encryption.
Users must control the encryption. That is why end-to-end encryption(PGP) works and has been around for more than 25 years.
PGP is a difficult concept to grasp at first, but once you wrap your head around it, you’ll feel more liberated and safe.
It is not clunky? Is terminal window clunky?
For anyone who wants to try PGP on a mac try GPGtools.
They have made a commendable job of making encryption and decryption of emails, and files easy.
This is how GPG integrated email looks on the native Apple mail client.
All emails are encrypted and signed using GPG. You own the encryption keys.
Encrypt and decrypt files, folders and disks with a click
Extracting colour palettes from an image
Trying out Colorthief a python package extract colour palettes from an image.
Trying out Colorthief a python package extract colour palettes from an image.
Was reading through an enhancement request on Pillow's github page. Currently Pillow does not give an built-in way to identify all dominant colours on an image. The suggestion was to port "Colorthief" package into Pillow.
Trying Colorthief.
Fairly simple and direct, pip install it.
Follow the instructions here and with little bit of help on how to map numpy arrays it is easy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from colorthief import ColorThief import numpy as np import matplotlib.pyplot as plt color_thief = ColorThief('/home/pk/Desktop/bd.png') dominant_color = color_thief.get_color(quality=1) """dominant_color 0 = 147 1 = 66 2 = 46""" color_palette = color_thief.get_palette(color_count=12) color_palette = np.asarray(color_palette)[np.newaxis, :, :] """ Color_palette = 0 = <numpy.array at 0x7f64b92173f0[6x1]> 0 = [136 53 35] 1 = [40 14 22] 2 = [195 117 89] 3 = [232 168 152] 4 = [213 130 107] 5 = [209 136 134]""" plt.imshow(color_palette); plt.axis('off'); plt.show(); |
Color Image into Grayscale using Python Image Processing Libraries | An Exploration
Exploring monochrome image processing using various Python image processing libraries
Processing Libraries used:
Libraries for image data wrangling:
From SciPy:
To get started, lets access the image file and bring it inside our script. Let us use the python os module to access and read the file into the script
We will also be importing "Image" module from Pillow(PIL) library
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | '''Exploring grayscale with Python using PIL, Skimage, NumPy and Matplotlib Libraries''' import os from PIL import Image, ImageColor, ImageOps from skimage import color import numpy as np import matplotlib.pyplot as plt import matplotlib.style as style import matplotlib.image as mpimg from exception import IOError '''Opening an image using Python's os module''' path = os.path.join(os.path.expanduser('~'), 'Desktop','color','img-4.jpg') img = Image.open(path) img.show() |
Lets read the image properties using PIL.image functions. To check if the right image is read, let's open it in the default image previewer of your OS.
1 2 3 4 5 6 7 8 9 10 11 | img = Image.open(path) img.show() #preview the image in the default image editor of your OS '''Image Properties''' print("filename:",img.filename) print("format:", img.format) print("mode:", img.mode) print("size:", img.size) print("width*height", img.width, "*", img.height) print("palette:", img.palette) print("Image Info:", img.info) |
The image properties
- filename: /home/pk/Desktop/color/img-4.jpg
- format: JPEG * mode: RGB
- size: (900, 601)
- width*height: 900 * 601
- palette: None
- imgInfo: dict_keys(['exif', 'dpi', 'photoshop', 'adobe', 'adobe_transform', 'icc_profile'])
Converting to Grayscale
Method 1: Averaging the R,G,B values.(non-linear)
This is the most basic of all grayscale conversion method. We take the average of R,G,B values of each pixel to arrive at a single value(ranging from 0 (black) to 255 (white).
As quoted here :
Some computer systems have computed brightness using (R+G+B)/3. This is at odds with the properties of human vision
Method 1: Averaging - R,G,B values Y = (R+G+B)/3
1 2 3 4 5 6 7 8 9 | """Method 1 - Averaging - R,G,B values """ #Python's Lambda(anonymous) expression. Apply simple math and convert to a list(of pixles) AllPixels = list(map(lambda x: int((x[0] + x[1] + x[2])/3), list(img.getdata()))) GreyscaleImg1 = Image.new("L", (img.size[0], img.size[1]), 255) #instantiate an image GreyscaleImg1.putdata(AllPixels) #Copies pixel list to this image GreyscaleImg1.show() #preview image plotHist(GreyscaleImg1,"Averaging") #plot a histogram |
The human eye always interprets different colors in a different way. The weights ranging in the order of Green, Red and Blue.
Taking into consideration the color perception, we have methods 2 and 3 below.
Method 2: LUMA-REC-601(non-linear)
Again quoting Charles Poynton,
If three sources appear red, green and blue, and have the same radiance in the visible spectrum, then the green will appear the brightest of the three because the luminous efficiency function peaks in the green region of the spectrum. The red will appear less bright, and the blue will be the darkest of the three. As a consequence of the luminous efficiency function, all saturated blue colors are quite dark and all saturated yellows are quite light. If luminance is computed from red, green and blue, the coefficients will be a function of the particular red, green and blue spectral weighting functions employed, but the green coefficient will be quite large, the red will have an intermediate value, and the blue coefficient will be the smallest of the three.
Method 2 - LUMA-REC-601 Y = ( R * 299/1000 + G * 587/1000 + B * 114/1000 )
1 2 3 4 5 6 7 8 9 | """"""Method 2 - LUMA-REC-601""" """ #Python's Lambda(anonymous) expression. Apply simple math and convert to a list(of pixles) AllPixels = list(map(lambda x: int(x[0]*(299/1000) + x[1]*(587/1000) + x[2]*(114/1000)), list(img.getdata()))) GreyscaleImg2 = Image.new("L", (img.size[0], img.size[1]), 255) #instantiate an image GreyscaleImg2.putdata(AllPixels) #Copies pixel list to this image GreyscaleImg2.show() #preview image plotHist(GreyscaleImg2,"REC-601") #plot a histogram |
The PIL image module has a convert function that helps to convert an image from one mode to another. To convert to grayscale, pass in "L" (luminance) as a mode parameter. When translating a color image to black and white (mode “L”), the library uses the ITU-R 601-2 luma transform
1 2 3 4 | #When translating a color image to black and white (mode “L”), the library uses the ITU-R 601-2 luma transform: grayImg = img.convert('L') grayImg.show() |
Learn more about LUMA REC.601 here.
Method 3 - LUMA-REC.709(non-linear)
Both REC.601 and REC.709 considers the difference in color perception( and hence different coefficients for R,G, B). But the major difference is as follows:
Quoting Charles Poynton, with respect to REC.60:
The coefficients 0.299, 0.587 and 0.114 properly computed luminance for monitors having phosphors that were contemporary at the introduction of NTSC television in 1953. However, these coefficients do not accurately compute luminance for contemporary monitors
Where as REC.709:
Contemporary CRT phosphors are standardized in Rec. 709 [9], to be described in section 17. The weights to compute true CIE luminance from linear red, green and blue (indicated without prime symbols), for the Rec. 709, are these:
Method 2 - LUMA-REC.709 Y = 0.2125 * R + 0.7154 * G + 0.0721 * B
1 2 3 4 5 6 7 8 9 | """"""Method 3 - LUMA-REC-709""" """ #Python's Lambda(anonymous) expression. Apply simple math and convert to a list(of pixles) AllPixels = list(map(lambda x: int(x[0]*(212/1000) + x[1]*(715/1000) + x[2]*(72/1000)), list(img.getdata()))) GreyscaleImg3 = Image.new("L", (img.size[0], img.size[1]), 255) #instantiate an image GreyscaleImg3.putdata(AllPixels) #Copies pixel list to this image GreyscaleImg3.show() #preview image plotHist(GreyscaleImg3,"REC-709") #plot a histogram |
Let’s dig down to see, how the math works at the pixel level:
The results from the grayscale conversion methods:






1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | def plotHist(grayImg, title): ImagingCore= grayImg.getdata() print(ImagingCore) #<ImagingCore object at 0x7f952e28aa10> print(type(ImagingCore)) #<class 'ImagingCore'> print(grayImg.getextrema()) #(0, 255) #Follwing returns a flat list of pixel values(ranging from 0-255). We'll convert these values into an array down below GrayPixels=list(grayImg.getdata()) print(type(GrayPixels)) #<class 'list'> # convert the list into an array. Matplotlib accepts array as a parameter to plot histogram GrayPixelsArray = np.array(GrayPixels) print (GrayPixelsArray.size) #540900 i.e width*height: 900 * 601 print (GrayPixelsArray.shape) #(540900,) print (GrayPixelsArray.dtype) #int64 print (GrayPixelsArray.ndim) #1-D array print(np.mean(GrayPixelsArray), np.median(GrayPixelsArray), np.std(GrayPixelsArray), np.max(GrayPixelsArray), np.min(GrayPixelsArray)) #64.90450730264374 66.0 31.959808127905852 255 0 plt.style.use('Solarize_Light2') plt.hist(GrayPixelsArray, bins = 255) plt.title(title) plt.show() |
Image Statistics: +------------+---------+---------+--------+------+-----+ | Grayscale | Mean | Median | Std | Max | Min | +------------+---------+---------+--------+------+-----+ +------------+---------+---------+--------+------+-----+ | Averaging | 64.90 | 66.0 | 31.95 | 255 | 0 | +------------+---------+---------+--------+------+-----+ | REC-601 | 77.76 | 76.0 | 41.38 | 255 | 0 | +------------+---------+---------+--------+------+-----+ | REC-709 | 86.23 | 82.0 | 47.94 | 254 | 0 | +------------+---------+---------+--------+------+-----+



Grayscale conversion using Scikit-image processing library
We will process the images using NumPy. NumPy is fast and easy while working with multi-dimensional arrays.
For instance an RGB image of dimensions M X N with their R,G,B channels are represented as a 3-D array(M,N,3). Similarly a grayscale image is represented as 2-D array(M,N). NumPy is fast and easy when it comes to doing calculations on big arrays(large images).
We’ll use plotting functions from Matplotlib to plot and view the processed image.
To convert to grayscale(non-linear):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import os import numpy as np import matplotlib.pyplot as plt import matplotlib.image as mpimg from skimage import color, io, data from skimage.viewer import ImageViewer from PyQt5 import QtCore, QtGui, QtWidgets img = io.imread('/home/pk/Desktop/color/img-4.jpg') #Fetch the image into the script """Reading the properties of the image""" #plt.imshow(img) #plt.show() #print(img) #Prints RGB values of each pixel across W*H as a 3D matrix(M,N,3) #print(type(img)) #<class 'numpy.ndarray'> #print(img.shape) #(601, 900, 3) """Splitting the image into R,G,B Channels""" R = img[:, :, 0] G = img[:, :, 1] B = img[:, :, 2] Gray = color.rgb2gray(img) # REC.709 | Y = 0.2125 R + 0.7154 G + 0.0721 B #Gray = (R*0.212)+(G*0.715)+(B*0.072) # or do the conversion math across 3 channels ## we shall use matplotlib to display the channels fig, ((ax1, ax2), (ax3,ax4)) = plt.subplots(nrows=2, ncols=2, figsize=(20,10)) ax1.imshow(R,cmap=plt.cm.Reds) ax1.set_title("RED Channel") ax2.imshow(G,cmap=plt.cm.Greens) ax2.set_title("GREEN Channel") ax3.imshow(B,cmap=plt.cm.Blues) ax3.set_title("BLUE Channel") ax4.imshow(Gray, cmap="gray") ax4.set_title("GRAYSCALE: rgb2gray(uses REC.709) ") plt.show() |
RGB image numpy.ndarray representation.
Plot of red, green, blue, and gray conversions.
Converting to GrayScale: The right way by linearization of sRGB by applying inverse gamma function.
All RGB images are gamma encoded.
Gamma encoding of images is used to optimize the usage of bits when encoding an image, or bandwidth used to transport an image, by taking advantage of the non-linear manner in which humans perceive light and color.
Where as Luminance is:
Luminance is a spectrally weighted but otherwise linear measure of light. The spectral weighting is based on how human trichromatic vision perceives different wavelengths of light.
The correct luminance value is calculated(by linearization using inverse gamma function) using the following steps:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | """ Applying Linearisation on a gamma encoded sRGB Image. In vChannel, Channel is color channel as in vR, VG, vB """ def linearize(vChannel): vChannelFlat = vChannel.ravel() #flatten 2-D array into 1-D array vChannelLinear= [] for i in vChannelFlat: if i <= 0.040: i = (i/12.92) vChannelLinear.append(i) else: i = pow((i+0.055)/(1.055),2.4) vChannelLinear.append(i) return np.asarray(vChannelLinear).reshape(601,900) R = img[:, :, 0] G = img[:, :, 1] B = img[:, :, 2] vR, vG, vB = R/255, G/255, B/255 "Calculating Relative Luminance" Ylin = (0.216* linearize(vR)) + (0.715* linearize(vG)) + (0.072* linearize(vB)) YlinFlat = Ylin.ravel() #converting into 1-D array to plot histogram Gray = color.rgb2gray(img) #scikit rgb2gray function(non-linearized) Grayflat = Gray.ravel() fig, ((ax1,ax2),(ax3,ax4)) = plt.subplots(2,2,figsize=(5,5)) ax1.imshow(Ylin, cmap="gray") ax1.set_title("Linear") ax2.imshow(Gray,cmap ="gray") ax2.set_title("Non-linear") ax3.hist(YlinFlat, bins = 255) #compare the histograms of linearized & non-linearized ax4.hist(Grayflat, bins = 255) plt.show() |



References:
- Some great answers from Stackoverflow: here, here and here.
- A great post on gamma correction.
- Another great source on linear transformation.
VIM
It takes a decade to master VIM they say. Mine is just beginning. I've seen how powerful the tool could be. It's like having a nitro boosters on fingers.
It takes a decade to master VIM they say. Mine is just beginning. I've seen how powerful the tool could be. It's like having a nitro boosters on fingers.
Starting to get used to "navigating/moving around" the text.
h,j, k, l
Ww, Bb
gg, G
3gg, 10gg
ctrl f, ctrl b
shift $, shift ^
Hello World from LINUX
My linux system is so humble and simple in its config.
I got a refurbished DELL Optiplex 9010, stripped all its fancy parts, loaded a 2010, Intel Pentium G2010 Dual Core processors with 128 GB SSD and runs on Ubuntu 18.04.3 LTS.
My current Macbook pro(2017) is taking a heavy pounding. Keyboard issues, slow processing speed, strange reboots with scary kernal warning messages.
May be I'm like too much of a task master.
So decided to shift the load.
- Personal and coding related work to linux.
- Professional work - Photography, design and video editing on the MacBook. I can't live without the Adobe Suite and FCPX
My linux system is so humble and simple in its config. I got a refurbished DELL Optiplex 9010, stripped all its fancy parts, loaded a 2010, Intel Pentium G2010 Dual Core processors with 128 GB SSD and runs on Ubuntu 18.04.3 LTS.
My desktop and some of the apps i’m getting used to.
Giving it back
Over the years, there have been a lot of software applications and online communities — open source to be specific — which I’ve benefited from directly by using them for work and indirectly because each one of them stood and are still standing up to something very specific — and that is wonderfully inspiring.
Over the years, there have been a lot of software applications and online communities — open source to be specific — which I’ve benefited from directly by using them for work and indirectly because each one of them stood and are still standing up to something very specific — and that is wonderfully inspiring.
It is only after subscribing to few of the core mailing lists it dawned on me that, help, however small, can help move the movement an inch forward.
As a first step, I’ve decided to contribute $1 every month to the following apps and communities
Please do check your computer: make a list of all the open-source applications that you are using — I emailed this question to few of my friends; On a average they use 4 applications/communities that are on open-source/public domain.
Did you find any application that you can live/work without? Go make a donation. Contribute!
Tools of the Trade
The following are the tools and applications that helps me get the job done; both personally and professionally(photography, video and design)
The following are the tools and applications that helps me get the job done; both personally and professionally(photography, video and design)
Hardware
Workstation
- MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
- Dell 21.5 inch (54.6 cm) Ultra Thin Bezel LED Monitor
- Bose QuietControl 30, Noise cancellation headphones
Photography
- Nikon D750 FX
- Nikon D3100 DX
- Canonet 35mm film
- Nikon F65 35mm film
- Yashica FX3 super 35mm film
- iPhone SE
- Godox AD600B(studio light)
- Godox V860 N(camera flash) * 2
- Zhiyun crane 2
- DJI Osmo Mobile 2
- iPad mini 2 - 20% of my reading happens here with iBooks & Kindle app for iPad.
Software:
Creative Suite:
- Photoshop CC
- Lightroom CC
- GIMP - for quick, lightweight photo edits.
- Inkscape - vector design
- Sketch - design
- Final cut pro
- Handbrake video transcoder
- Apple Keynote
Writing & Research
- Ulysses - Notemaking
- LaTeX - for documentation
- Brother 220 manual typewriter
- Ember(now discontinued) - Capture screenshots, videos, and organize them under tags(visual research)
- The Wayback machine lets you capture web pages and store it as an archive for reference and sharing.
- Both Ember and The Wayback Machine are my humble attempt to try Zettelkasten.
Tasks
- ProtonMail
- Omnifocus - To-do list
- Rescuetime - Productivity tracker
- Freedom - distraction(social media) blocker.
- Keychain - password management
- A private phpBB forum for internal communication, project management, and knowledge wiki.— One place for discussions & decisions.
Storage:
- Amazon drive - Backup for: personal projects, and photos on the iPhone
- AWS S3 - Backup for professional projects
- Squarespace CMS. This website and fridaymatinee studio are hosted there.
Fitness:
- Garmin Forerunner 15 GPS watch.
- Smashrun - Training and running intelligence integrated with Garmin Connect.
Music:
- Apple Music
- Panasonic Bahadur AM | FM radio - I live alone and gets too lonely in the mornings. Most of the time it is for just the white noise.
- GPO vinyl record player
Communication:
- Panasonic KX-TG1612 Cordless Phone - Landline for work-related communications.
Browsers:
- Google Chrome
- Tor - with duckduckgo; for ads-blocked privacy conscious browsing. Mostly used during focused research.