<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://yedhu.me/feed.xml" rel="self" type="application/atom+xml" /><link href="https://yedhu.me/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-07-12T23:21:32+05:30</updated><id>https://yedhu.me/feed.xml</id><title type="html">Yedhu Krishnan</title><subtitle>Notes on programming, books, and things I&apos;m learning.</subtitle><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><entry><title type="html">Time Tracker App for macOS</title><link href="https://yedhu.me/posts/time-tracker/" rel="alternate" type="text/html" title="Time Tracker App for macOS" /><published>2026-07-12T05:30:00+05:30</published><updated>2026-07-12T05:30:00+05:30</updated><id>https://yedhu.me/posts/time-tracker</id><content type="html" xml:base="https://yedhu.me/posts/time-tracker/"><![CDATA[<p>It has been more than 15 years since I tried building a native desktop app. The last one was during my school days, when I built a calculator in Visual C++. That was fun and exciting, and my skills were limited. I knew the basics of C, and I drag-and-dropped different buttons and boxes to make the UI. I enjoyed building that app, although I was mostly the only one who saw it.</p>

<p>Fast forward 15+ years, and I spent some time building another native app. This time, it was a macOS time tracker. In terms of skill set, I am starting from scratch this time since I have no experience building a macOS app. But developing an app is easier with AI tools if you know what you want. I was able to vibecode a working version in two days, tailored for my needs.</p>

<p>In addition to normal time tracker features like the ability to start, pause, and stop the timer and set an agenda, I wanted a few other features as well:</p>

<ol>
  <li>A customizable reminder (nudge) to track the time during work hours. I could also customize the work hours in the app.</li>
  <li>A configurable nudge interval and a snooze option.</li>
  <li>A prompt at the end of the session to reflect on how well it went. I could write a short summary of the session if I need to.</li>
  <li>An option to rate the session from 1 to 5.</li>
  <li>Sync across my MacBook and Mac Mini since I switch between them often.</li>
</ol>

<p>I’m sure there are apps with some or most of these features, but the prospect of building something by myself was tempting. Also, it gives me full control over the app’s features and appearance.</p>

<p><img src="/assets/img/2026/time-tracker-ui.png" alt="Time Tracker" width="75%" /></p>

<p class="image-caption"><em>The time tracker UI</em></p>

<p>This was the first app I built for the Apple ecosystem. For anyone curious, the source code and the disk images are available here: <a href="https://github.com/yedhukrishnan/time-tracker" target="_blank">time-tracker</a></p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Software Development" /><category term="apps" /><category term="macos" /><category term="productivity" /><summary type="html"><![CDATA[It has been more than 15 years since I tried building a native desktop app. The last one was during my school days, when I built a calculator in Visual C++. That was fun and exciting, and my skills were limited. I knew the basics of C, and I drag-and-dropped different buttons and boxes to make the UI. I enjoyed building that app, although I was mostly the only one who saw it.]]></summary></entry><entry><title type="html">Image Manipulation in Python</title><link href="https://yedhu.me/posts/image-manipulation-in-python/" rel="alternate" type="text/html" title="Image Manipulation in Python" /><published>2022-10-28T05:30:00+05:30</published><updated>2022-10-28T05:30:00+05:30</updated><id>https://yedhu.me/posts/image-manipulation-in-python</id><content type="html" xml:base="https://yedhu.me/posts/image-manipulation-in-python/"><![CDATA[<p>If you haven’t read the last post in the series, please read it here: <a href="/posts/the-r-g-and-b-in-an-image/">The R, G, and B in an Image</a>.</p>

<p>Let’s see how we increase/decrease the brightness or contrast of an image and some other transformations. We already know that images are NumPy arrays in Python. All we need to do now is to perform matrix operations.</p>

<p>Let’s start by reading a greyscale image.</p>

<p><img src="/assets/img/2022/grayscale-image.webp" alt="A gray tree" />
<em>Image Courtesy: pexels.com</em></p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">imageio</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">imageio</span><span class="p">.</span><span class="nf">imread</span><span class="p">(</span><span class="sh">'</span><span class="s">grey_tree.jpg</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>

<p>Let’s say we would like to increase the brightness of the image. To do that, add a constant value to each pixel. This is how we do that in NumPy</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">bright_image</span> <span class="o">=</span> <span class="n">image</span> <span class="o">+</span> <span class="mi">50</span>
<span class="n">bright_image</span><span class="p">[</span><span class="n">bright_image</span> <span class="o">&gt;</span> <span class="mi">255</span><span class="p">]</span> <span class="o">=</span> <span class="mi">255</span>
<span class="n">imageio</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">"</span><span class="s">bright_grey_tree.jpg</span><span class="sh">"</span><span class="p">,</span> <span class="n">bright_image</span><span class="p">.</span><span class="nf">astype</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">uint8</span><span class="p">))</span>
</code></pre></div></div>

<p>In the first line, I added 50 to each pixel value. When we do that, some pixels will go above the 8-bit image threshold of 255. When that happens, we set it back to 255, the highest possible value. Then I saved the matrix as an 8-bit image.</p>

<p>As you see in the snippet above, NumPy makes it easier to change all the pixel values without iterating over them in a loop. That is the beauty of the library.</p>

<p>If we save the image, we will see a brighter image like this:</p>

<p><img src="/assets/img/2022/bright-image.webp" alt="A bright gray tree" /></p>

<p>You can guess what we would do to decrease the brightness now. We need to subtract a constant value from each pixel. If the number goes negative, set it to 0.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">dark_image</span> <span class="o">=</span> <span class="n">image</span> <span class="o">-</span> <span class="mi">50</span>
<span class="n">dark_image</span><span class="p">[</span><span class="n">dark_image</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">imageio</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">"</span><span class="s">dark_grey_tree.jpg</span><span class="sh">"</span><span class="p">,</span> <span class="n">dark_image</span><span class="p">.</span><span class="nf">astype</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">uint8</span><span class="p">))</span>
</code></pre></div></div>

<p>And the resulting image looks like this:</p>

<p><img src="/assets/img/2022/dark-image.webp" alt="A dark gray tree" /></p>

<p>We can adjust the brightness in percentages too. Convert the percentage value to the pixel value using the formula:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pixel_value = 255 * (percentage_value / 100)
</code></pre></div></div>

<p>To adjust the contrast of an image, instead of adding or removing a constant, we multiple each pixel with a number:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">high_contrast_image</span> <span class="o">=</span> <span class="n">image</span> <span class="o">*</span> <span class="mf">1.5</span>
<span class="n">high_contrast_image</span><span class="p">[</span><span class="n">high_contrast_image</span> <span class="o">&gt;</span> <span class="mi">255</span><span class="p">]</span> <span class="o">=</span> <span class="mi">255</span>
<span class="n">imageio</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">"</span><span class="s">high_contrast_grey_tree.jpg</span><span class="sh">"</span><span class="p">,</span> <span class="n">high_contrast_image</span><span class="p">.</span><span class="nf">astype</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">uint8</span><span class="p">))</span>
<span class="n">low_contrast_image</span> <span class="o">=</span> <span class="n">image</span> <span class="o">*</span> <span class="mf">0.5</span>
<span class="n">low_contrast_image</span><span class="p">[</span><span class="n">low_contrast_image</span> <span class="o">&gt;</span> <span class="mi">255</span><span class="p">]</span> <span class="o">=</span> <span class="mi">255</span>
<span class="n">imageio</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">"</span><span class="s">high_contrast_grey_tree.jpg</span><span class="sh">"</span><span class="p">,</span> <span class="n">low_contrast_image</span><span class="p">.</span><span class="nf">astype</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">uint8</span><span class="p">)</span>
</code></pre></div></div>

<p>Here are the corresponding versions of the image.</p>

<p><img src="/assets/img/2022/high-contrast-image.webp" alt="A high contrast gray tree" /> <img src="/assets/img/2022/low-contrast-image.webp" alt="A low contrast gray tree" /></p>

<p>As you can see, multiplying by a number greater than 1 increases the contrast, while multiplying by a number less than 1 decreases the contrast.</p>

<p>What if you want to flip the image? All you need to do is to reverse the rows in the matrix:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">flipped_image</span> <span class="o">=</span> <span class="n">image</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="p">:]</span>
<span class="n">imageio</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">"</span><span class="s">flipped_image.jpg</span><span class="sh">"</span><span class="p">,</span> <span class="n">flipped_image</span><span class="p">.</span><span class="nf">astype</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">uint8</span><span class="p">)</span>
</code></pre></div></div>

<p><img src="/assets/img/2022/flipped-image.webp" alt="A flipped gray tree" /></p>

<p><code class="language-plaintext highlighter-rouge">image[::-1, :]</code> reverses the rows in the image <code class="language-plaintext highlighter-rouge">(::-1)</code> and keeps the columns intact (<code class="language-plaintext highlighter-rouge">:</code>). You can get the mirror image by doing the same for columns instead of rows.</p>

<p>I recommend going through the <a href="https://numpy.org/doc/1.23/user/absolute_beginners.html">NumPy docs</a> to learn more about how these operators work. Read an image, and play around with it. Search about various matrix operations, read how you can do that with NumPy, and try them on your image. See how the image transforms when you do that.</p>

<p>In future posts, I will explain how we can do color image manipulation. For now, please share your feedback and thoughts about these posts.</p>

<p>I’ve also published the article on Medium: <a href="https://medium.com/@yedhu/image-manipulation-in-python-98db79cc0c1">Image Manipulation in Python</a>.</p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Digital Image Processing" /><category term="python" /><category term="digital-image-processing" /><summary type="html"><![CDATA[If you haven’t read the last post in the series, please read it here: The R, G, and B in an Image.]]></summary></entry><entry><title type="html">The R, G, and B in an Image</title><link href="https://yedhu.me/posts/the-r-g-and-b-in-an-image/" rel="alternate" type="text/html" title="The R, G, and B in an Image" /><published>2019-10-08T05:30:00+05:30</published><updated>2019-10-08T05:30:00+05:30</updated><id>https://yedhu.me/posts/the-r-g-and-b-in-an-image</id><content type="html" xml:base="https://yedhu.me/posts/the-r-g-and-b-in-an-image/"><![CDATA[<p>If you haven’t read the last post in the series, please read it here: <a href="/posts/introduction-to-digital-image-processing-in-python">Introduction to Digital Image Processing in Python</a>.</p>

<p>A typical color image consists of three color channels: red, green and blue. Each color channel has 8 bits and can represent 256 distinct values. Using a combination of all three channels, we can create <code class="language-plaintext highlighter-rouge">256 x 256 x 256</code> colors, which is around 16-million colors. You might have heard this term before. Now you know where that came from.</p>

<p>In this post, we will learn more about the different components of an image. Let us try everything in a python console, which can be started by running the following command in a terminal. If you haven’t installed Python yet, please follow the <a href="/posts/introduction-to-digital-image-processing-in-python">instructions from my previous post</a>.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python3
</code></pre></div></div>

<p>You can download and use the sample image given below. It has different colors, and that’s what we need.</p>

<p><img src="/assets/img/2019/colors.webp" alt="A colorful image with red, green, blue, yellow, orange and white straws" />
<em>Image Courtesy: Max Pixel</em></p>

<p>Import the library and load the image:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">imageio</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">imageio</span><span class="p">.</span><span class="nf">imread</span><span class="p">(</span><span class="sh">'</span><span class="s">colors.jpg</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>

<p>Now we have the image as a NumPy array in our console. If you want to see the dimensions of the image, run:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">image</span><span class="p">.</span><span class="n">shape</span>
</code></pre></div></div>

<p>You will get something like <code class="language-plaintext highlighter-rouge">(426, 640, 3)</code>. This means the image has a height of 426 pixels, a width of 640 pixels, and three color channels. We are interested in the color channels for now. Let us write the individual channels to separate image files:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">imageio</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">'</span><span class="s">red.jpg</span><span class="sh">'</span><span class="p">,</span> <span class="n">image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">])</span>
<span class="n">imageio</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">'</span><span class="s">green.jpg</span><span class="sh">'</span><span class="p">,</span> <span class="n">image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">1</span><span class="p">])</span>
<span class="n">imageio</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">'</span><span class="s">blue.jpg</span><span class="sh">'</span><span class="p">,</span> <span class="n">image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">2</span><span class="p">])</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">:</code> is used to get all values. For example, <code class="language-plaintext highlighter-rouge">image[:, :, 0]</code> means get all rows, all columns, and the first (at index 0) color channel, which is the red channel. I’ll talk more about Indexing and Slicing in the next post. If you are curious, you can learn more about here: <a href="https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html">Indexing and Slicing</a> (or <a href="https://www.tutorialspoint.com/numpy/numpy_indexing_and_slicing.htm">here</a>).</p>

<p>If you open the files you just created, you would see something like this.</p>

<p><img src="/assets/img/2019/r.webp" alt="r" /> <img src="/assets/img/2019/g.webp" alt="g" /> <img src="/assets/img/2019/b.webp" alt="b" />
<em>The red, blue and green components</em></p>

<p>Why do they all look grey?</p>

<p>That is because they are single-channel images now. They will be saved as greyscale images. If you see the shape of the green component using the command:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">1</span><span class="p">].</span><span class="n">shape</span>
</code></pre></div></div>

<p>You will see <code class="language-plaintext highlighter-rouge">(426, 460)</code>. The color channel part is missing. Each pixel will have a single 8-bit value (unlike in RGB, which has three 8-bit values for R, G and B).</p>

<p>But if observe carefully, you will see that the grey value in the red-channel image corresponds to the amount of red in the color image.</p>

<p><img src="/assets/img/2019/red.webp" alt="Color distribution for red channel" /></p>

<p>The distribution of red color. On the extreme left, the value of red would be 0 and on the extreme right, it would be 255. As we move from left to write, the value gradually increases.</p>

<p>For example, see a red straw in the color image. A red pixel would be <code class="language-plaintext highlighter-rouge">[255, 0, 0]</code>, which is on the right side of the color distribution image shown above. The green and blue components will be zero.</p>

<p>In red.jpg image, the color of the same straw is white, which is 255. And the same straw appears black (0) in both green and blue component images because a red pixel doesn’t have blue or green components.</p>

<p><img src="/assets/img/2019/all-colors.webp" alt="All color channels" /></p>

<p>Color distribution for greyscale, red, green and blue channels. In all cases, the left side is 0 and the right side is 255.
If you want to see the actual colors instead of just grey images, you need to retain all three channels and set the values on the other channels to zero. For example, to get the red component, set the green and blue channel values to 0, as shown below:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">red_image</span> <span class="o">=</span> <span class="n">image</span><span class="p">.</span><span class="nf">copy</span><span class="p">()</span>
<span class="n">red_image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">red_image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">imageio</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">'</span><span class="s">red_image.jpg</span><span class="sh">'</span><span class="p">,</span> <span class="n">red_image</span><span class="p">)</span>
</code></pre></div></div>

<p>Here, I made a copy of the image and set all the blue and green channel values to zero. This is another handy usage of <code class="language-plaintext highlighter-rouge">:</code> to set the same value to multiple pixels in a NumPy array.</p>

<p>Similarly, you can create the green and blue images. They will now look like this:</p>

<p><img src="/assets/img/2019/r-color.webp" alt="R color" /> <img src="/assets/img/2019/g-color.webp" alt="G color" /> <img src="/assets/img/2019/b-color.webp" alt="B color" />
<em>The colorful red, green and blue components</em></p>

<p>Notice that for yellow straws, both red and green components are active, but the blue component is missing (black in color). The pixel values would be closer to <code class="language-plaintext highlighter-rouge">[255, 255, 0]</code>.</p>

<p>White color in RGB image would be represented as <code class="language-plaintext highlighter-rouge">[255, 255, 255]</code>. Grey pixels in the RGB image will have the same value for all components. When we take the average of all three values, we get the same number. For example, a grey value <code class="language-plaintext highlighter-rouge">[57, 57, 57]</code> in RGB will have value 57 in a greyscale image. We discussed about converting an <a href="/posts/lessons-on-digital-image-processing-1">RGB image to greyscale in the first post</a>.</p>

<p>Now you know how RGB images are made; by using a combination of values on R, G, and B color channels. The same technique is used in all modern color displays, including mobile and TV screens. Here is a <a href="https://www.youtube.com/watch?v=3BJU2drrtCM">cool video by The Slow Mo Guys</a> explaining how that works on TVs.</p>

<p>In the coming posts, I’ll explain about processing a digital image using Python. For now, please share your feedback and suggestions.</p>

<p>Originally published on Medium: <a href="https://medium.com/analytics-vidhya/the-r-g-and-b-in-an-image-971b9aecfb7f" target="_blank" rel="noopener">The R, G, and B in an Image</a>.</p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Digital Image Processing" /><category term="python" /><category term="digital-image-processing" /><summary type="html"><![CDATA[If you haven’t read the last post in the series, please read it here: Introduction to Digital Image Processing in Python.]]></summary></entry><entry><title type="html">Introduction to Digital Image Processing in Python</title><link href="https://yedhu.me/posts/introduction-to-digital-image-processing-in-python/" rel="alternate" type="text/html" title="Introduction to Digital Image Processing in Python" /><published>2019-09-29T05:30:00+05:30</published><updated>2019-09-29T05:30:00+05:30</updated><id>https://yedhu.me/posts/introduction-to-digital-image-processing-in-python</id><content type="html" xml:base="https://yedhu.me/posts/introduction-to-digital-image-processing-in-python/"><![CDATA[<p>If you haven’t read the first post in the series, read it here: <a href="/posts/lessons-on-digital-image-processing-1/">Lessons on Digital Image Processing</a>.</p>

<p>In this second part, let’s write some actual code. We will be writing all our code in Python.</p>

<p>Python makes processing and manipulating images very easy. NumPy and SciPy packages available for Python help us to perform scientific computing, mainly operations on matrices, which is of interest to us. We already saw images are just matrices in computers.</p>

<p>The easiest way to install SciPy and NumPy in a Linux machine is using Python package manager pip.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>python3-pip
<span class="nb">sudo </span>pip3 <span class="nb">install </span>numpy scipy
</code></pre></div></div>

<p>Let’s install two more packages which are necessary to load and display an image in Python.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pip3 <span class="nb">install </span>imageio matplotlib
</code></pre></div></div>

<p>Now, to load and display an image, all you need is a few lines of code. Make sure you have an image file in the same directory where your code is residing.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">imageio</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>

<span class="c1"># Load the image
</span><span class="n">image</span> <span class="o">=</span> <span class="n">imageio</span><span class="p">.</span><span class="nf">imread</span><span class="p">(</span><span class="sh">'</span><span class="s">color_flower.jpg</span><span class="sh">'</span><span class="p">)</span>

<span class="c1"># Display the image
</span><span class="n">plt</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">image</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">show</span><span class="p">()</span>
</code></pre></div></div>

<p>That’s all. The code is self-explanatory. I have added necessary comments to help you understand.</p>

<p>We have a color image. How do we create a greyscale image from it?</p>

<p>We already know a color image has three values in each pixel positions for representing red, green and blue intensity values. In a greyscale image, there is only one value. All we need to do is to convert these three values into a single value.
How do we do that?</p>

<p>Just take the average of all the three values!</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>grey pixel value = (red + green + blue) / 3
</code></pre></div></div>

<p>Let us implement this in Python. We use a NumPy array to store the image in Python. NumPy provides a convenient function to take the average or mean on any axis. In the case of an RGB image, axis = 0 is row-wise, axis = 1 is column-wise and axis = 2 is channel-wise. We need a channel-wise sum.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gray_image = image.mean(axis = 2)
</code></pre></div></div>

<p>This one line of code converts the color image to a grayscale image. It does the same thing as the following lines of code:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="n">row</span><span class="p">,</span> <span class="n">col</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">image</span><span class="p">.</span><span class="n">shape</span>

<span class="c1"># Define an empty array for grey image
</span><span class="n">grey_image</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">((</span><span class="n">row</span><span class="p">,</span> <span class="n">col</span><span class="p">))</span>

<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">row</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">col</span><span class="p">):</span>
        <span class="c1"># Store the average of R, G, B values
</span>        <span class="n">grey_image</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">image</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">].</span><span class="nf">mean</span><span class="p">()</span>

<span class="n">plt</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">grey_image</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="sh">'</span><span class="s">gray</span><span class="sh">'</span><span class="p">);</span> <span class="n">plt</span><span class="p">.</span><span class="nf">show</span><span class="p">()</span>
</code></pre></div></div>

<p>The above code is much slower than the previous version. However, understanding this is important if you are new to this.</p>

<p>We just created the grey version of the image. Now, we can convert this into a binary image. A grey image pixel values range from 0 to 255. In binary, it can take only two values. In some representations, we use 0 and 1. Here, we’ll use 0 (for black) and 255 (for white).</p>

<p>How do we convert a grey image into a binary image? The usual method is to set a threshold value T. If the pixel value is above the threshold, we’ll set it to 255. If it is below, we’ll set it to 0. Here, we can take the threshold as the median grey value, which is 128.</p>

<p>Here is the extended version of the code.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">binary_image</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">((</span><span class="n">row</span><span class="p">,</span> <span class="n">col</span><span class="p">))</span>

<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">row</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">col</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">grey_image</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="mi">128</span><span class="p">:</span>
            <span class="n">pixel</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">pixel</span> <span class="o">=</span> <span class="mi">255</span>

        <span class="n">binary_image</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">pixel</span>

<span class="n">plt</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">binary_image</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="sh">'</span><span class="s">gray</span><span class="sh">'</span><span class="p">);</span> <span class="n">plt</span><span class="p">.</span><span class="nf">show</span><span class="p">()</span>
</code></pre></div></div>

<p>And the short version is just two lines:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>binary_image = grey_image.copy()
binary_image[binary_image &lt;= 128] = 0
binary_image[binary_image &gt; 128]  = 255
</code></pre></div></div>

<p>That is it! NumPy takes care of updating all the pixel values to 0 or 255 depending on whether they are above or below the threshold.</p>

<p>Now we know about color, greyscale and binary images, and we know how to convert a color image to grey and then to binary. We will see more image processing techniques and python code in the upcoming posts.</p>

<p>For now, please share your feedback and opinion about these posts.</p>

<p>Originally published on Medium: <a href="https://medium.com/analytics-vidhya/lessons-on-digital-image-processing-2-983d8bab98c8">Introduction to Digital Image Processing in Python</a>.</p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Digital Image Processing" /><category term="python" /><category term="digital-image-processing" /><summary type="html"><![CDATA[If you haven’t read the first post in the series, read it here: Lessons on Digital Image Processing.]]></summary></entry><entry><title type="html">Book Review: Malice</title><link href="https://yedhu.me/posts/malice/" rel="alternate" type="text/html" title="Book Review: Malice" /><published>2018-12-28T11:07:00+05:30</published><updated>2018-12-28T11:07:00+05:30</updated><id>https://yedhu.me/posts/malice</id><content type="html" xml:base="https://yedhu.me/posts/malice/"><![CDATA[<blockquote>
  <p><em>Everyone has secrets. And everyone has the right to keep them. Even if they’re dead.</em></p>
</blockquote>

<p>Keigo Higashino never fails to amuse me with perfect crimes and gripping mystery behind it. As usual, by the end of first chapter, the murder was committed, the how part was almost clear and we had a prime suspect. The rest of the story is a quest to find the motive behind the murder. Just when I thought it was over, the book had over 40% remaining and it was full of twists and turns.</p>

<p>Kunihiko Hidaka, a famous Japanese author, is found murdered in his house days before he was supposed to move to Canada. The body was discovered by his wife and his best friend. While investigating, Detective Kyoichiro Kaga comes across information that questions the authenticity of the author and the relationship with his friend.</p>

<p>The story resembles Devotion of Suspect X in many ways. There are old colleagues who know each other well. The conversation between them leads to a turning point in the investigation. But while trying to uncover the plot, the detective has to dig up far more than the suspect’s past known to him.</p>

<p>Unlike other stories, Malice is written from the point of view of the detective and the victim’s friend. This helps in setting the plot at the beginning. It also helped to break some conventional assumptions I had about the story.</p>

<blockquote>
  <p><em>Apparently, it won’t do just to tell the reader what a particular character is like. The author needs to show their habits or their words and let the reader form an image on their own.</em></p>
</blockquote>

<p>I place Malice at the third position of my list of favourite Higashino novels. It comes after Devotion of Suspect X and Salvation of a Saint, pushing Journey Under the Midnight Sun and Midsummer’s Equation one step backward. But I recommend this to anyone who loves crime thrillers.</p>

<p>Originally published on my blog: <a href="https://mirrordimension.wordpress.com/2018/12/28/malice/" target="_blank" rel="noopener">Malice</a></p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Book Review" /><category term="books" /><category term="fiction" /><summary type="html"><![CDATA[Everyone has secrets. And everyone has the right to keep them. Even if they’re dead.]]></summary></entry><entry><title type="html">Book Review: Factfulness</title><link href="https://yedhu.me/posts/factfulness/" rel="alternate" type="text/html" title="Book Review: Factfulness" /><published>2018-11-19T05:30:00+05:30</published><updated>2018-11-19T05:30:00+05:30</updated><id>https://yedhu.me/posts/factfulness</id><content type="html" xml:base="https://yedhu.me/posts/factfulness/"><![CDATA[<blockquote>
  <p>Step-by-step, year-by-year, the world is improving. Not on every single measure every single year, but as a rule. Though the world faces huge challenges, we have made tremendous progress. This is the fact-based worldview.</p>
</blockquote>

<p>Factfulness is one book I would recommend to anyone who wants to have a clear perspective about the world based on facts. It was written by Hans Rosling; a medical doctor, professor of international health and a public educator. I recently found this TED video; and interesting one which will help you know him better: The best stats you’ve ever seen. The book is a compilation of his years of research and experience, and is co-written by his son Ola Rosling and daughter-in-law Anna Rosling. I heard about it first when Bill Gates mentioned this book in his blog. He explains how it helped him not to talk about ‘developed’ and ‘developing’ countries.</p>

<p><img src="/assets/img/2018/factfulness-cover.jpeg" alt="Factfulness book cover" /></p>

<p>We live with misconceptions about the current state of the world. We hear the bad side of everything everyday and we think the world is slowly deteriorating. This over-dramatic view is what Hans Rosling demystifies in Factfulness. He presents why and how we are wrong through a simple quiz and explanations. It doesn’t end there. He further dives into what causes these distorted views, how to look out for the warning signs, and how to avoid them.</p>

<p>He describes ten instincts, in ten chapters, which are responsible for this. Although these one line explanations is nothing compared to the chapters in the book, if you do not like spoilers, you can skip this part.</p>

<ul>
  <li><strong>The gap instinct</strong>: the natural tendency to divide everything incorrectly into two groups</li>
  <li><strong>The negativity instinct</strong>: which always makes us see the negative face than the positive one</li>
  <li><strong>The straight line instinct</strong>: the assumption that a straight line will always continue like the same in the future when we look at graphs</li>
  <li><strong>The fear instinct</strong>: frightening things that get in our way and blocks rational thinking</li>
  <li><strong>The size instinct</strong>: when lonely numbers are presented to us, we wrongly assume the severity of the issue</li>
  <li><strong>The generalisation instinct</strong>: which makes us think something that works for someone, works for others too</li>
  <li><strong>The destiny instinct</strong>: when people think something will never change because they don’t observe gradual progress</li>
  <li><strong>The single perspective instinct</strong>: the problem of a single perspective limiting our imagination</li>
  <li><strong>The blame instinct</strong>: when we find comfort in pointing fingers rather than finding the root cause</li>
  <li><strong>The urgency instinct</strong>: which makes us act fast without thinking, by creating a sense of unnecessary urgency</li>
</ul>

<p>He presents every one of these with case studies and beautiful bubble charts. All the facts are backed by data, which are compiled and verified by international organisations. Also, the author is not afraid to admit how he had these instincts in the past, some of which are quintessential and resulted in terrifying repercussions.</p>

<p>The chapters are clear, concise and well structured with explanations and data. There was never a dull moment reading this book, and I enjoyed it all of it! I can count the non-fictions I loved from cover to cover on the fingers (The last one was Delivering Happiness, by late <em>Tony Hsieh</em>, founder of Zappos)</p>

<p><img src="/assets/img/2018/factfulness.jpg" alt="Factfulness" />
<em>“The world cannot be understood without numbers. But the world cannot be understood with numbers alone.”  – Hans Rosling</em></p>

<p>This book was an eye-opener for me. Also, this is not about optimism. The author himself says he is not an optimist, but a ‘possibiist’; someone who neither hopes without reason, nor fears without reason, someone who constantly resists the overdramatic worldview. It doesn’t say the world is good. It says the world is both good and bad; they coexist together. The learnings from the book can be applied in about everything in our daily life.</p>

<p>Originally published on my blog: <a href="https://mirrordimension.wordpress.com/2018/11/29/factfulness/" target="_blank" rel="noopener">Factfulness</a></p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Book Review" /><category term="books" /><category term="non-fiction" /><summary type="html"><![CDATA[Step-by-step, year-by-year, the world is improving. Not on every single measure every single year, but as a rule. Though the world faces huge challenges, we have made tremendous progress. This is the fact-based worldview.]]></summary></entry><entry><title type="html">Book Review: Journey Under the Midnight Sun</title><link href="https://yedhu.me/posts/journey-under-the-midnight-sun/" rel="alternate" type="text/html" title="Book Review: Journey Under the Midnight Sun" /><published>2018-10-29T17:19:00+05:30</published><updated>2018-10-29T17:19:00+05:30</updated><id>https://yedhu.me/posts/journey-under-the-midnight-sun</id><content type="html" xml:base="https://yedhu.me/posts/journey-under-the-midnight-sun/"><![CDATA[<blockquote>
  <p>You know how the sun rises and sets at a certain time each day? In the same way, all of our lives have a day and night. But it’s not set like it is with the sun. Some people walk forever in the sunlight, and some people have to walk through the darkest night their whole lives. When people talk about being afraid, what they’re afraid of is that their sun will set. That the light they love will fade.</p>
</blockquote>

<p>Keigo Higashino is an acclaimed mystery novelist from Japan, and one of my favourite authors. He started writing novels in the 80’s and was popular in Japan for quite some time. But the world came to know about him when his crime thriller, <em>Yōgisha X no Kenshin</em>, was translated to English as <em>Devotion of Suspect X</em>. He writes perfect crimes which are, indeed, page-turners.</p>

<p><em>Journey Under the Midnight Sun</em> takes us through a time span of two decades. A murder is committed, and the specifics of it remains unresolved. Time goes by, life of everyone associated changes, but the tenacity of Sagasaki, the investigation officer, doesn’t. He pays attention to the ramifications of the murder all these years, and continues his search for answers even after his retirement, which leads to interesting discovery about the past.</p>

<p>The intricate structure of the plot is purely mesmerising and shows the sheer brilliance of the storyteller. You come across these unanticipated subplots, with new characters and events, that just pops up and connect with the main storyline afterward. The ending of the book is kind of abrupt, but gives a logical closure to the crusade.</p>

<p><em>“When you wander in the dark too long, you start to see things that aren’t really there.” — Keigo Higashino</em></p>

<p>If you haven’t read any books by Keigo Higashino, I would recommend reading Devotion of Suspect X first. I had trouble remembering all these Japanese character names. But that one didn’t have many characters and it helped me to focus on the story instead of going back and forth to see who is who. This wouldn’t be a problem if you have read Japanese novels before.</p>

<p>Originally published on my blog: <a href="https://mirrordimension.wordpress.com/2018/10/29/journey-under-the-midnight-sun/" target="_blank" rel="noopener">Journey Under the Midnight Sun</a></p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Book Review" /><category term="books" /><category term="fiction" /><summary type="html"><![CDATA[You know how the sun rises and sets at a certain time each day? In the same way, all of our lives have a day and night. But it’s not set like it is with the sun. Some people walk forever in the sunlight, and some people have to walk through the darkest night their whole lives. When people talk about being afraid, what they’re afraid of is that their sun will set. That the light they love will fade.]]></summary></entry><entry><title type="html">Book Review: Creative Struggle</title><link href="https://yedhu.me/posts/zen-pencils-creative-struggle/" rel="alternate" type="text/html" title="Book Review: Creative Struggle" /><published>2018-10-16T05:30:00+05:30</published><updated>2018-10-16T05:30:00+05:30</updated><id>https://yedhu.me/posts/zen-pencils-creative-struggle</id><content type="html" xml:base="https://yedhu.me/posts/zen-pencils-creative-struggle/"><![CDATA[<blockquote>
  <p>And that’s what separates the pros from the hobbyists, the ability to create when you don’t feel like creating. The ability to “master their disinclination”</p>
</blockquote>

<p><img src="/assets/img/2018/curie.webp" alt="Marie Curie" /></p>

<p>Zen Pencils always lift my spirits. They are good for a quick shot of inspiration. The latest book is no different. Like Zen Pencils: Cartoon Quotes from Inspirational Folks and Dream the Impossible Dream, Creative Struggle is yet another collection of inspirational comics, most of which are available to read for free in <a href="https://www.zenpencils.com/" target="_blank">zenpencils.com</a>. I love to keep hardcopy versions because they are worth it, and are good for gifting.</p>

<p><img src="/assets/img/2018/creative-struggle-cover.jpg" alt="Factfulness book cover" /></p>

<p>Gavin Aung Than gives colours to these magnificent and inspirational quotes by famous personalities and transform them into stories. He illustrates the struggles they went through, how they conquered the fears and created their best pieces of work. He also gives a glimpse of the unexplored sides of these famous personalities we know.</p>

<p>Originally published on my blog: <a href="https://mirrordimension.wordpress.com/2018/10/16/zen-pencils-creative-struggle-illustrated-advice-from-masters-of-creativity/" target="_blank" rel="noopener">Zen Pencils — Creative Struggle: Illustrated Advice from Masters of Creativity</a></p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Book Review" /><category term="books" /><category term="comics" /><summary type="html"><![CDATA[And that’s what separates the pros from the hobbyists, the ability to create when you don’t feel like creating. The ability to “master their disinclination”]]></summary></entry><entry><title type="html">Lessons on Digital Image Processing</title><link href="https://yedhu.me/posts/lessons-on-digital-image-processing-1/" rel="alternate" type="text/html" title="Lessons on Digital Image Processing" /><published>2018-03-18T22:31:00+05:30</published><updated>2018-03-18T22:31:00+05:30</updated><id>https://yedhu.me/posts/lessons-on-digital-image-processing-1</id><content type="html" xml:base="https://yedhu.me/posts/lessons-on-digital-image-processing-1/"><![CDATA[<p>This is the first one of a series of posts I am planning to write about image processing. I intend this post for students who are new to the concepts of image processing. The code snippets, if there are any, will be in simple Python. If you want to learn Python, there is an <a href="https://www.learnpython.org/">interactive tutorial here</a>. You can also check out <a href="https://docs.python.org/3/tutorial/">Python tutorial</a> on the official website.</p>

<p>There is always room for improving these posts. I would like to read your comments and feedback about the series.</p>

<h2 id="digital-image">Digital Image</h2>

<p>Let’s start with the basic concept of image processing. A digital image can be represented as a matrix, a rectangular array of integers called <a href="https://en.wikipedia.org/wiki/Pixel">pixels</a>. Each pixel represents a small color box.</p>

<p>Consider a small matrix of size 2 x 2, where each is represented with an 8-bit integer. So, the values can range from 0 to 255 (²⁰ to ²⁸-1). Consider a simple example given below.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>255  0
0    255
</code></pre></div></div>
<p>The image represented by the above matrix looks like this.</p>

<p><img src="/assets/img/2018/2x2_image.webp" alt="The 2x2 image" />
<em>The 2x2 image</em></p>

<p>Here, the value 255 represents a white color, while 0 represents a black. This is a <a href="https://en.wikipedia.org/wiki/Binary_image">bilevel or binary image</a>. Each of the values in the matrix is a pixel, the smallest units of an image. In some cases, the binary images are represented with a single bit. In some cases, 0 represents black and 1 represents white, or vice versa.</p>

<p>This is just an enlarged representation of 4 pixels in an image. In a real case, the pixels are tiny, and you can represent complex figures with larger matrices. In fact, if the number of pixels per inch increases, the quality of the image increases. The same concept is used in mobile phone and computer displays.</p>

<p><img src="/assets/img/2018/binary_image.webp" alt="The 853x1280 binary image of a flower" />
<em>A 853x1280 binary image of a flower (courtesy: pixabay.com)</em></p>

<p>As you might be already thinking, binary images do not represent actual images we see. In reality, there should be more colors than just black and white. How do we represent that?</p>

<p>We already mentioned that the pixel values are 8 bits. They can take any value between 0 and 255. As the value increases from 0 to 255, the color changes from black to grey to white. In total, there are 256 shades of grey! Such an image is called a <a href="https://en.wikipedia.org/wiki/Grayscale">grayscale image</a>.</p>

<p><img src="/assets/img/2018/grayscale_image.webp" alt="The same flower image in greyscale" />
<em>The same flower image in greyscale, where each pixel value ranges from 0 to 255 (courtesy: pixabay.com)</em></p>

<p>But where are the colors? We stumble upon color images more often than grey images. That is where the color theory comes into the picture. We know the white light can be formed from three primary colors: red, green and blue. These three primary colors can be mixed in different ratios to get different colors.</p>

<p>The same technique is used in digital images. So far, we have seen pixels with just one value. In a color image, each pixel takes three values, one for red, green and blue. All these values range from 0 to 255. This gives us a total of 255 * 255 * 255 possible combinations of colors, which is also known as 16 million colors. Imagine a color image as three greyscale matrices stacked together, where the matrices represent these three color channels.</p>

<p><img src="/assets/img/2018/color_image.webp" alt="The same flower image in color" />
<em>Much better! Here, each pixel is a combination of three values, representing R, G and B (courtesy: pixabay.com)</em></p>

<p>The color model described here is known as an <a href="https://en.wikipedia.org/wiki/RGB_color_model">RGB model</a>. There are other models as well. But for now, let us stick with this one. In the upcoming posts, I will explore more topics in digital image processing. I will also include simple algorithms implementations in Python.</p>

<p>For now, please share your feedback and opinion. I would definitely improve based on that.</p>

<p>I’ve also published the article on Medium: <a href="https://medium.com/analytics-vidhya/lessons-on-digital-image-processing-1-b7a1fa3acfe9">Lessons on Digital Image Processing (#1)</a>.</p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Digital Image Processing" /><category term="python" /><category term="digital-image-processing" /><summary type="html"><![CDATA[This is the first one of a series of posts I am planning to write about image processing. I intend this post for students who are new to the concepts of image processing. The code snippets, if there are any, will be in simple Python. If you want to learn Python, there is an interactive tutorial here. You can also check out Python tutorial on the official website.]]></summary></entry><entry><title type="html">Book Review: Only Time Will Tell</title><link href="https://yedhu.me/posts/only-time-will-tell/" rel="alternate" type="text/html" title="Book Review: Only Time Will Tell" /><published>2018-02-25T23:56:00+05:30</published><updated>2018-02-25T23:56:00+05:30</updated><id>https://yedhu.me/posts/only-time-will-tell</id><content type="html" xml:base="https://yedhu.me/posts/only-time-will-tell/"><![CDATA[<blockquote>
  <p>Some people stand by you in your darkest hour, while others walk away; only a select few march towards you and become even closer friends.</p>
</blockquote>

<p>Sometimes, reading is as good as experiencing. We immerse ourself in the world created by the author and refuse to let go of it. Clifton Chronicles is one that would remain with me for quite some time. The series is even worth reading a second time.</p>

<p><em>Only Time Will Tell</em> was there in my to-read list for the past one and half years. But I started reading it only last week, and it didn’t take me a week to finish it!</p>

<p>This is my first proper Jeffrey Archer book. I’ve read one of his short stories some time ago, which was just okay. But the first book in the <em>Clifton Chronicles</em> was entirely different. A few chapters into this book, I realised why the series is called the most ambitious work of the author in four decades. The connection of the story to the pre world war era and other historical events during that time shows the effort and dedication the author has put in to create such a beautiful story. .</p>

<p>The style of storytelling is also worth mentioning. The story cycles between main characters; telling the story from a first person view and then from a third person view. You might read the same incident twice; different side of it through different perspectives. The author himself told in an interview that he could have written this in only a third person perspective. He considered the former as a challenge. I would say that he was successful in implementing it.</p>

<p>Only Time Will Tell, tells the story of Harry Clifton, who lives in Bristol with his Mom. The story starts around the time when he was five years old, although there are flashbacks of the incidents before that. I want to tell more about the story, but I can’t do it without spoiling it in a great deal.</p>

<p>So, here comes the spoilers.</p>

<p>I loved the characters, especially Maisie Clifton, Captain Jack Tarrant (Old Jack) and Emma Barrington; they proves how passionate and true a love can be as a mom, mentor and lover respectively. I loved Harry and Emma as a couple. I just hope they are not siblings.</p>

<p>There are many beautiful moments in the story. Here are a few of my favourites. The first one is where young Harry goes to buy a gift. Towards the end, we all know Old Jack paid 10 shillings for the watch that costs 16 shillings, and told Mr. Deakins to mention the price as 6 shillings to Harry. But when Harry tells him that he is buying the watch for his Mom, Mr. Deakins says he can have it for 5 shillings. That is simply heart-touching.</p>

<p>And, how can I miss Harry and Emma quoting <em>Romeo and Juliet</em> before parting for the night?</p>

<blockquote>
  <p>‘Good night, good night, parting is such sweet sorrow,’ she whispered.</p>

  <p>‘That I shall say good night till it be morrow,’ Harry replied.</p>
</blockquote>

<p>They are amazing together, and I wish I could see them playing Romeo and Juliet on stage.</p>

<p>Originally published on my blog: <a href="https://mirrordimension.wordpress.com/2018/02/25/only-time-will-tell/" target="_blank" rel="noopener">Only Time Will Tell</a></p>]]></content><author><name>Yedhu Krishnan</name><email>yk.strobe281@passmail.com</email></author><category term="Book Review" /><category term="books" /><category term="fiction" /><summary type="html"><![CDATA[Some people stand by you in your darkest hour, while others walk away; only a select few march towards you and become even closer friends.]]></summary></entry></feed>