{"id":690,"date":"2023-06-27T12:19:45","date_gmt":"2023-06-27T16:19:45","guid":{"rendered":"https:\/\/brian.digitalmaddox.com\/blog\/?p=690"},"modified":"2024-01-16T20:24:38","modified_gmt":"2024-01-17T01:24:38","slug":"image-processing-for-beginners-image-zooming","status":"publish","type":"post","link":"https:\/\/brian.digitalmaddox.com\/blog\/?p=690","title":{"rendered":"Image Processing for Beginners: Image Zooming"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Today I\u2019m finally going to finish up the series I started on image processing. The goal of this series is to dispel any myths that algorithms that work on images make things up or do strange, arcane magic. The data is there in the images already, and algorithms that work on them simply make things more visible to a human.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">My idea for this originally started when people claimed that zooming in on an image using an iPhone was somehow changing it. The claim (politically motivated) was that it changed the semantic content of the image by zooming in or out. So today I\u2019ll wrap up this series by going over how you zoom an image (or make it larger \/ smaller).&nbsp; Note this post will be a bit more technical than the last one as I am including code to demonstrate what I am doing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Semantic content of an image refers to the meaning or information that the image conveys, such as objects, scenes, actions, attributes, etc.  For example, if you take a picture of a cat sitting on a table in your kitchen, then the semantic content would be each of the objects that are in that image (cat, table, kitchen).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Images are resized for you automatically all the time, and you are never aware of it mostly.&nbsp; Your web browser will scale an image so that it fits on your screen.&nbsp; Mobile devices scale images such that you can fit them on the device display.&nbsp; You may even have \u201cpinch to zoom\u201d in on an image so you can see things more clearly.&nbsp; So ask yourself, when you have zoomed in on an image, do new objects suddenly appear in it?&nbsp; Does an elephant suddenly appear when you zoom in or out of a picture of your children?&nbsp; You would have noticed this by now should it happen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Yes, any time you resize an image you do technically change it, as you have to map pixels from the original to the new size.&nbsp; However, no resizing operation changes the semantic content of the image.&nbsp; People have been mapping things and rescaling them long before computers have existed.&nbsp; Architects, draftsmen, cartographers, and others were transforming and resizing things before electricity was discovered.&nbsp; Just because a computer does it does not mean that suddenly objects get inserted into the image or that the meaning of the image gets changed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I\u2019ll be using <a href=\"https:\/\/opencv.org\/\" data-type=\"URL\" data-id=\"https:\/\/opencv.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">OpenCV<\/a> 4 and <a href=\"https:\/\/www.python.org\/\" data-type=\"URL\" data-id=\"https:\/\/www.python.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Python<\/a> 3. For those unaware, OpenCV is an open source computer vision library that has been around for a long time and is used in thousands of projects. The algorithms in it are some of the best around and have been vetted by experts in the field.&nbsp; The example image I will be using is a public domain image of a fish as can be seen below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0134.jpeg\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"427\" src=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0134.jpeg\" alt=\"\" class=\"wp-image-705\" srcset=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0134.jpeg 640w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0134-300x200.jpeg 300w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0134-450x300.jpeg 450w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption class=\"wp-element-caption\">Public Domain Photo of a Fish<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">To play along at home, I have the source code for this blog post at <a href=\"https:\/\/github.com\/briangmaddox\/blog_opencv_resizing_example\">https:\/\/github.com\/briangmaddox\/blog_opencv_resizing_example<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first thing we do with our sample image is to load it in using OpenCV, print the dimensions, and then display it.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Load in our input image\ninput_image = cv2.imread(\"1330-sole-fish.jpg\")\n\n# Get the dimensions of the original image\nheight, width, channels = input_image.shape\n\n# Print out the dimensions\nprint(f\"Image Width: {width} Height: {height}\")\n\n# Display the original image to the user\ncv2.imshow(\"Original Image\", input_image)\ncv2.waitKey(0)\ncv2.destroyAllWindows()<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When we run this code, we see our small fish image in a window:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0135.jpeg\"><img loading=\"lazy\" decoding=\"async\" width=\"759\" height=\"380\" src=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0135.jpeg\" alt=\"\" class=\"wp-image-706\" srcset=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0135.jpeg 759w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0135-300x150.jpeg 300w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0135-500x250.jpeg 500w\" sizes=\"auto, (max-width: 759px) 100vw, 759px\" \/><\/a><figcaption class=\"wp-element-caption\">Image of the fish displayed by OpenCV in a window<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Next we will do a \u201cdumb\u201d resize of the image.&nbsp; Here we double each pixel in the X- and Y-directions.&nbsp; This has the effect of making the image 2x large, effectively zooming in to the image.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">empty_mat = numpy.zeros((height * 2, width * 2, channels), dtype=numpy.uint8)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here empty_mat is an empty image that has been initialized to all zeroes.&nbsp; <a href=\"https:\/\/numpy.org\/\" data-type=\"URL\" data-id=\"https:\/\/numpy.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Numpy<\/a> is a well known array library that OpenCV and other packages are built on.&nbsp; When OpenCV and Python load an image, they <a href=\"https:\/\/docs.opencv.org\/4.x\/d6\/d6d\/tutorial_mat_the_basic_image_container.html\" data-type=\"URL\" data-id=\"https:\/\/docs.opencv.org\/4.x\/d6\/d6d\/tutorial_mat_the_basic_image_container.html\" target=\"_blank\" rel=\"noreferrer noopener\">store<\/a> it in what is basically a three dimensional array.&nbsp; You can think of this as a box where each red, green, and blue channel of the image is contained in the box.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We do the following loop now to copy the pixel to the output empty_mat:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">for y in range(height):\n    for x in range(width):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixel = input_image[y, x]\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;empty_mat[y * 2, x * 2] = pixel\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;empty_mat[y * 2, x * 2 + 1] = pixel\n &nbsp;&nbsp;&nbsp;&nbsp; &nbsp; empty_mat[y * 2 + 1, x * 2] = pixel\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;empty_mat[y * 2 + 1, x * 2 + 1] = pixel<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I used a simple loop and assignments to make it easier to see what I am doing.&nbsp; This loop simply goes through each row of the input image and copies that pixel to four pixels in the output image, effectively doubling the size and zooming the image.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now we display both the original image and the doubled one.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cv2.imshow(\"Original Image\", input_image)\ncv2.imshow(\"Doubled image\", empty_mat)\ncv2.waitKey(0)\n\ncv2.destroyAllWindows()<\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0139.jpeg\"><img loading=\"lazy\" decoding=\"async\" width=\"1524\" height=\"594\" src=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0139.jpeg\" alt=\"\" class=\"wp-image-710\" srcset=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0139.jpeg 1524w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0139-300x117.jpeg 300w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0139-1024x399.jpeg 1024w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0139-768x299.jpeg 768w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0139-500x195.jpeg 500w\" sizes=\"auto, (max-width: 1524px) 100vw, 1524px\" \/><\/a><figcaption class=\"wp-element-caption\">Both the original image and the doubled image displayed by OpenCV<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">In the above screenshot, we can see that the image has indeed been \u201czoomed\u201d in and is now twice the size of the original.&nbsp; Semantically, both images are equal to each other.&nbsp; You can see the jaggedness of the fish in the doubled image due to the simplistic nature of the resize.&nbsp; The main take away from this is that it is still the same image, even if it is larger than the original.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Most applications that let you zoom in or resize images use something a bit smarter than a simple doubling of each pixel.&nbsp; As you can see with the above images, the simple \u201cdoubling\u201d results in a jagged image that becomes less visually pleasing as the zoom multiplier gets larger.&nbsp; This is because to double an image using the simple method, each pixel becomes four pixels.&nbsp; Four times larger means eight pixels, and so on.&nbsp; This method also becomes much more complicated if the zoom factor is not an even multiple of two.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Images today are resized using mathematical interpolations.&nbsp; Wikipedia defines <a href=\"https:\/\/en.wikipedia.org\/wiki\/Interpolation\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Interpolation\" target=\"_blank\" rel=\"noreferrer noopener\">interpolation<\/a> as \u201ca type of estimation, a method of constructing (finding) new data new points based on the range of a discrete set of known data points.\u201d&nbsp; \u201cAh ha!\u201d you might say, this sounds like things are being made up.&nbsp; And yes they are, but data is not being made up out of the blue.&nbsp; Instead, interpolations use existing data to mathematically predict data to fill in the gaps. Google, Apple, and other mapping applications use interpolations to fill in the gaps of your position to display on the screen in-between calculating your exact position using the satellites.&nbsp; Our brains do it when we reach out to catch a fast ball.&nbsp; Weather and financial forecasters use it every day.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Interpolations have a long history in mathematics.&nbsp; The Babylonians were using linear and other interpolations as far back as the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Babylonian_mathematics\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Babylonian_mathematics\" target=\"_blank\" rel=\"noreferrer noopener\">300\u2019s BCE<\/a> to predict the motions of celestial bodies.&nbsp; As time has gone on, mathematicians have devised better and more accurate methods of predicting values based on existing ones.&nbsp; Over time, we have gone from the relatively simplistic <a href=\"https:\/\/mathworld.wolfram.com\/PiecewiseConstantFunction.html\" data-type=\"URL\" data-id=\"https:\/\/mathworld.wolfram.com\/PiecewiseConstantFunction.html\" target=\"_blank\" rel=\"noreferrer noopener\">piecewise constant interpolations<\/a> to Gaussian processes.&nbsp; Each advance has made better and closer predictions to what the missing values actually are.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Consider an example using <a href=\"https:\/\/en.wikipedia.org\/wiki\/Linear_interpolation\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Linear_interpolation\" target=\"_blank\" rel=\"noreferrer noopener\">linear interpolation<\/a>.&nbsp; This type of problem is often taught in geometry and other math classes.&nbsp; Assume that we have points on a two-dimensional XY axis such as below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0137.jpeg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"678\" src=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0137-1024x678.jpeg\" alt=\"\" class=\"wp-image-708\" srcset=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0137-1024x678.jpeg 1024w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0137-300x199.jpeg 300w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0137-768x508.jpeg 768w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0137-453x300.jpeg 453w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0137.jpeg 1070w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Plot of the function y=x with the points (2,2) missing.<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Here we see we are given a series of (1,1), (3,3), (4,4), (5,5), (6,6), and (7,7).&nbsp; This is in fact a plot of the function y = x, except I omitted the point (2,2).&nbsp; We can eyeball and see that the missing y value for x=2 is in fact 2, but let us go through the math.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The formula for linear interpolation is: <img loading=\"lazy\" decoding=\"async\" width=\"125\" height=\"43\" class=\"wp-image-709\" style=\"width: 125px;\" src=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2023\/06\/IMG_0138.jpeg\" alt=\"\" srcset=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2023\/06\/IMG_0138.jpeg 366w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2023\/06\/IMG_0138-300x103.jpeg 300w\" sizes=\"auto, (max-width: 125px) 100vw, 125px\" \/>.\u00a0 So if we want to solve for the point where x=2, (x1,y1) will be the point (1,1) and (x2, y2) will be the point (3,3).\u00a0 Plugging these numbers in we get <img loading=\"lazy\" decoding=\"async\" width=\"125\" height=\"49\" class=\"wp-image-714\" style=\"width: 125px;\" src=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2023\/06\/IMG_0143.jpeg\" alt=\"\" srcset=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2023\/06\/IMG_0143.jpeg 480w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2023\/06\/IMG_0143-300x118.jpeg 300w\" sizes=\"auto, (max-width: 125px) 100vw, 125px\" \/>, which indeed gives us y=2 for x=2.\u00a0 No magic here, just math.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Other types of interpolations, such as <a href=\"https:\/\/en.wikipedia.org\/wiki\/Monotone_cubic_interpolation\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Monotone_cubic_interpolation\" target=\"_blank\" rel=\"noreferrer noopener\">cubic<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Spline_interpolation\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Spline_interpolation\" target=\"_blank\" rel=\"noreferrer noopener\">spline<\/a>, and so on, also have mathematical equations that calculate new values based on existing values.&nbsp; This point is important to note.&nbsp; <strong>All interpolations use math to calculate new values based on existing ones.<\/strong>&nbsp; These interpolations have been used over hundreds of years, and are the basis for many things we use today.&nbsp; No magic, no guessing, no making things up.&nbsp; I think we can trust them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So let us get back to image processing.&nbsp; OpenCV fortunately can use interpolation to resize an image.&nbsp; As a reminder, we typically do this so that the image is more pleasing to the eye.&nbsp; Interpolations give us images that are not blocky as in the case of the simple image doubling technique.&nbsp; First we will use linear interpolation to double the size of the image<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">double_width = width * 2\ndouble_height = height * 2\nlinear_double_image = cv2.resize(input_image, (double_width, double_height), interpolation=cv2.INTER_LINEAR)\n\n# Now display both the original and the linear interpolated image to compare.\ncv2.imshow(\"Original Image\", input_image)\ncv2.imshow(\"Linear Interpolated image\", linear_double_image)\ncv2.waitKey(0)\ncv2.destroyAllWindows()<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To make things explicit, we set new dimensions to twice the width and height of the image and use linear interpolation to scale the image up.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0140.jpeg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"391\" src=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0140-1024x391.jpeg\" alt=\"\" class=\"wp-image-711\" srcset=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0140-1024x391.jpeg 1024w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0140-300x114.jpeg 300w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0140-768x293.jpeg 768w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0140-500x191.jpeg 500w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0140.jpeg 1525w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Original image and a linearly interpolated 2x image displayed with OpenCV<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Here we see that the interpolated image is not as blocky as the simple pixel doubling image, meaning that yes the new image is a bit different from the original.&nbsp; However, nothing new has been added to the image.&nbsp; It has not been distorted and the same semantic content has been preserved.&nbsp; We can look at what has happened by examining the coordinates at pixel (0,0) in the original image.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let us take this farther now.&nbsp; What happens if we increase to four times the original size?<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Linear interpolation to quad size\nquad_width = width * 4\nquad_height = height * 4\n\nlinear_quad_image = cv2.resize(input_image, (quad_width, quad_height), interpolation=cv2.INTER_LINEAR)\n\n# Now display both the original and the linear interpolated image to compare.\ncv2.imshow(\"Original Image\", input_image)\ncv2.imshow(\"Linear Interpolated 4x image\", linear_quad_image)\ncv2.waitKey(0)\ncv2.destroyAllWindows()<\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0141.jpeg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"510\" src=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0141-1024x510.jpeg\" alt=\"\" class=\"wp-image-712\" srcset=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0141-1024x510.jpeg 1024w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0141-300x149.jpeg 300w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0141-768x382.jpeg 768w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0141-1536x765.jpeg 1536w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0141-500x249.jpeg 500w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0141.jpeg 1972w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Original image and a linearly interpolated 4x image displayed by OpenCV<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Again, creating a 4x-size image does not introduce any new objects or change the semantic meaning of the image. You may notice that it looks a bit more blurry than the 2x image.&nbsp; This is because linear interpolation is a simple process.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let us see what it looks like using a more rigorous cubic interpolation to create a 4x image.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Cubic interpolation\ncubic_quad_image = cv2.resize(input_image, (quad_width, quad_height), interpolation=cv2.INTER_CUBIC)\n\n# Now display both the original and the linear interpolated image to compare.\ncv2.imshow(\"Original Image\", input_image)\ncv2.imshow(\"Cubic Interpolated 4x image\", cubic_quad_image)\ncv2.waitKey(0)\ncv2.destroyAllWindows()<\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0142.jpeg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"514\" src=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0142-1024x514.jpeg\" alt=\"\" class=\"wp-image-713\" srcset=\"https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0142-1024x514.jpeg 1024w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0142-300x151.jpeg 300w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0142-768x386.jpeg 768w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0142-1536x771.jpeg 1536w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0142-500x251.jpeg 500w, https:\/\/brian.digitalmaddox.com\/blog\/wp-content\/uploads\/2024\/01\/IMG_0142.jpeg 1975w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Original image and the cubic interpolated 4x image displayed by OpenCV<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">We can see that the image does not have as pronounced blockiness that the linearly interpolated image has.&nbsp; Yes, it is not exactly the same as the original image as we did not simply double each pixel.&nbsp; However, <strong>the semantic contents of the image are the same, even using a different interpolation method.<\/strong>&nbsp; We did not introduce anything new into the image by resizing it.&nbsp; The meaning of the image is the same as it was before.&nbsp; It is just larger so we can see it better.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is time to wrap this up as it is a longer post than I intended.&nbsp; You can see from the above that resizing (or zooming in on) an image does not change the content of the image.&nbsp; We did not turn the fish into a shark by enlarging it.&nbsp; We did not add another fish to the image by enlarging it.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I encourage you to try this on your own at home.&nbsp; Pull out your phone, take a picture, and then zoom in on it.&nbsp; Your camera likely takes such a high resolution that displaying it on your screen actually reduces some detail, so that you have to zoom in to see the fine detail in the image.&nbsp; Ask yourself though, is the meaning of the image changed by zooming in or out on it?&nbsp; Are they still your children, or did zooming in turn them into something else?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I hope that the next time you hear something in the news about image processing, you realize that every algorithm that does this is just math. It is either math to bring out fine details that you cannot normally see in the case of dark images, or math that makes the image larger so that you can better see the smile on a child.&nbsp; The content of the image is not changed, it is always semantically the same as the original image.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today I\u2019m finally going to finish up the series I started on image processing. The goal of this series is to dispel any myths that algorithms that work on images make things up or do strange, arcane magic. The data &hellip; <a href=\"https:\/\/brian.digitalmaddox.com\/blog\/?p=690\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":691,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[37],"class_list":["post-690","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-opencv","tag-computer-vision"],"_links":{"self":[{"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/690","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=690"}],"version-history":[{"count":4,"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/690\/revisions"}],"predecessor-version":[{"id":715,"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/690\/revisions\/715"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=\/wp\/v2\/media\/691"}],"wp:attachment":[{"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=690"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=690"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brian.digitalmaddox.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=690"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}