{"id":6146,"date":"2022-12-19T08:59:30","date_gmt":"2022-12-19T13:59:30","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=6146"},"modified":"2022-12-20T16:40:38","modified_gmt":"2022-12-20T21:40:38","slug":"avoid-jpeg-for-image-analysis","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2022\/12\/19\/avoid-jpeg-for-image-analysis\/","title":{"rendered":"Avoid Using JPEG for Image Analysis"},"content":{"rendered":"<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01 Transitional\/\/EN\">\r\n<div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '>\r\n<p><em>Note added 20-Dec-2022: I wrote this post with lossy JPEG in mind. If you work with DICOM data, see Jeff Mather's note in the comments below about the use of lossless JPEG in DICOM.<\/em><\/p>\r\n<span>I have recently been reading a lot of image processing and image analysis questions on MATLAB Answers. Anyone who does the same will quickly come across comments and answers posted by the prolific <\/span><a href = \"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/1343420\"><span>Image Analyst<\/span><\/a><span>, a MATLAB Answers MVP who has posted an astounding 34,600+ answers in the last 11 years.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>I always enjoy the side commentary that I sometimes find in these answers. For example, I came across this code comment in one answer:<\/span><\/div><div class = 'preformatted-matlab' style = 'margin: 10px 3px 10px 55px; padding: 10px 10px 10px 5px; '><div  style = 'border-left: 0px none rgb(33, 33, 33); border-right: 0px none rgb(33, 33, 33); border-top: 0px none rgb(33, 33, 33); border-bottom: 0px none rgb(33, 33, 33); border-radius: 0px; padding: 0px; line-height: 15.6px; min-height: 16px; white-space: pre; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; font-size: 12px; '><span style=\"white-space: pre\"><span style=\"color: rgb(0, 128, 19);\">% This is a horrible image.  NEVER use JPG format <\/span><\/span><\/div><div  style = 'border-left: 0px none rgb(33, 33, 33); border-right: 0px none rgb(33, 33, 33); border-top: 0px none rgb(33, 33, 33); border-bottom: 0px none rgb(33, 33, 33); border-radius: 0px; padding: 0px; line-height: 15.6px; min-height: 16px; white-space: pre; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; font-size: 12px; '><span style=\"white-space: pre\"><span style=\"color: rgb(0, 128, 19);\">% for image analysis.  Use PNG, TIFF, or BMP instead.<\/span><\/span><\/div><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>Today, I want to take the opportunity to endorse this statement and to elaborate on it a bit. Why do we not love JPEG files for image analysis?<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>The reason is that JPEG is a <\/span><span style=' font-style: italic;'>lossy<\/span><span> image compression format. Lossy compression methods achieve substantial reduction in file size by using <\/span><a href = \"https:\/\/en.wikipedia.org\/wiki\/Lossy_compression\"><span>\"inexact approximations and partial data discarding to represent the content.\"<\/span><\/a><span> With JPEG compression, roughly speaking, pixels are grouped into blocks, and then the pixel data in each block is quantized and partially discarded. The method is called <\/span><span style=' font-style: italic;'>lossy<\/span><span> because you can't get the exact original image pixel data back from a JPEG file; information has been lost.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>I've written about lossy vs. lossless compression before; see my <\/span><a href = \"https:\/\/blogs.mathworks.com\/steve\/2013\/05\/02\/jpeg-versus-png-lossy-and-lossless-image-compression\/\"><span>02-May-2013 post<\/span><\/a><span>.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>Usually, this form of compression is acceptable for viewing photographs because the compression method exploits properties of human visual perception so that the information loss is relatively imperceptible. In image analysis applications, though, when you are trying to automatically detect or measure things, the pixel data imperfections in the JPEG file could mess it up.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>Let me show you a couple of different versions of this picture:<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><img class = \"imageNode\" src = \"https:\/\/blogs.mathworks.com\/steve\/files\/never_use_jpg_01.png\" width = \"396\" height = \"297\" alt = \"IMG_6129-reduced-size.png\" style = \"vertical-align: baseline; width: 396px; height: 297px;\"><\/img><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>The original picture was shot in RAW mode (which is lossless) and saved as a 4032x3024 PNG file, with a file size of 23 MB.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>Here is a highly magnified view of the center of the picture. You can see the individual pixels.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><img class = \"imageNode\" src = \"https:\/\/blogs.mathworks.com\/steve\/files\/never_use_jpg_02.png\" width = \"468\" height = \"353\" alt = \"lossless-magnified.png\" style = \"vertical-align: baseline; width: 468px; height: 353px;\"><\/img><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>I created a JPEG version of this file with a file size of only about 1 MB. If you look at the entire picture, the JPEG version looks like the original.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><img class = \"imageNode\" src = \"https:\/\/blogs.mathworks.com\/steve\/files\/never_use_jpg_03.png\" width = \"468\" height = \"353\" alt = \"lossy-version-reduced.png\" style = \"vertical-align: baseline; width: 468px; height: 353px;\"><\/img><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>But if you look at a highly magnified view, you can see that pixel data has been partially discarded in a block-wise fashion.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><img class = \"imageNode\" src = \"https:\/\/blogs.mathworks.com\/steve\/files\/never_use_jpg_04.png\" width = \"468\" height = \"353\" alt = \"lossy-magnified.png\" style = \"vertical-align: baseline; width: 468px; height: 353px;\"><\/img><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span><\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>You can probably imagine how this might affect object detection and measurement.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>So, as Image Analyst says, stick to lossless formats such as PNG or TIFF for your image analysis applications.<\/span><\/div>\r\n<script type=\"text\/javascript\">var css = '.variableValue { width: 100% !important; } .embeddedOutputsMatrixElement,.eoOutputWrapper .matrixElement {    min-height: 18px;    box-sizing: border-box;} .embeddedOutputsMatrixElement .matrixElement,.eoOutputWrapper  .matrixElement,.rtcDataTipElement .matrixElement {    position: relative;} .matrixElement .variableValue,.rtcDataTipElement .matrixElement .variableValue {    white-space: pre;    display: inline-block;    vertical-align: top;    overflow: hidden;} .embeddedOutputsMatrixElement.inlineElement {} .embeddedOutputsMatrixElement.inlineElement .topHeaderWrapper {    display: none;} .embeddedOutputsMatrixElement.inlineElement .veTable .body {    padding-top: 0 !important;    max-height: 100px;} .inlineElement .matrixElement {    max-height: 300px;} .embeddedOutputsMatrixElement.rightPaneElement {} .rightPaneElement .matrixElement,.rtcDataTipElement .matrixElement {    overflow: hidden;    padding-left: 9px;} .rightPaneElement .matrixElement {    margin-bottom: -1px;} .embeddedOutputsMatrixElement .matrixElement .valueContainer,.eoOutputWrapper .matrixElement .valueContainer,.rtcDataTipElement .matrixElement .valueContainer {    white-space: nowrap;    margin-bottom: 3px;} .embeddedOutputsMatrixElement .matrixElement .valueContainer .horizontalEllipsis.hide,.embeddedOutputsMatrixElement .matrixElement .verticalEllipsis.hide,.eoOutputWrapper .matrixElement .valueContainer .horizontalEllipsis.hide,.eoOutputWrapper .matrixElement .verticalEllipsis.hide,.rtcDataTipElement .matrixElement .valueContainer .horizontalEllipsis.hide,.rtcDataTipElement .matrixElement .verticalEllipsis.hide {    display: none;} .embeddedOutputsVariableMatrixElement .matrixElement .valueContainer.hideEllipses .verticalEllipsis, .embeddedOutputsVariableMatrixElement .matrixElement .valueContainer.hideEllipses .horizontalEllipsis {    display:none;} .embeddedOutputsMatrixElement .matrixElement .valueContainer .horizontalEllipsis,.eoOutputWrapper .matrixElement .valueContainer .horizontalEllipsis {    margin-bottom: -3px;} .eoOutputWrapper .embeddedOutputsVariableMatrixElement .matrixElement .valueContainer {    cursor: default !important;} .embeddedOutputsVariableElement {    white-space: pre-wrap;    word-wrap: break-word;    min-height: 18px;    max-height: 250px;    overflow: auto;} .variableElement {} .embeddedOutputsVariableElement.inlineElement {} .inlineElement .variableElement {} .embeddedOutputsVariableElement.rightPaneElement {    min-height: 16px;} .rightPaneElement .variableElement {    padding-top: 2px;    padding-left: 9px;} .variableNameElement {    margin-bottom: 3px;    display: inline-block;} \/* * Ellipses as base64 for HTML export. *\/.matrixElement .horizontalEllipsis,.rtcDataTipElement .matrixElement .horizontalEllipsis {    display: inline-block;    margin-top: 3px;    \/* base64 encoded version of images-liveeditor\/HEllipsis.png *\/    width: 30px;    height: 12px;    background-repeat: no-repeat;    background-image: url(\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAJCAYAAADO1CeCAAAAJUlEQVR42mP4\/\/8\/A70xw0i29BUDFPxnAEtTW37wWDqakIa4pQDvOOG89lHX2gAAAABJRU5ErkJggg==\");} .matrixElement .verticalEllipsis,.textElement .verticalEllipsis,.rtcDataTipElement .matrixElement .verticalEllipsis,.rtcDataTipElement .textElement .verticalEllipsis {    margin-left: 35px;    \/* base64 encoded version of images-liveeditor\/VEllipsis.png *\/    width: 12px;    height: 30px;    background-repeat: no-repeat;    background-image: url(\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAZCAYAAAAIcL+IAAAALklEQVR42mP4\/\/8\/AzGYgWyFMECMwv8QddRS+P\/\/KyimlmcGUOFoOI6GI\/UVAgDnd8Dd4+NCwgAAAABJRU5ErkJggg==\");} \/* Styling that is common to warnings and errors is in diagnosticOutput.css *\/.embeddedOutputsErrorElement {    min-height: 18px;    max-height: 250px;    overflow: auto;} .embeddedOutputsErrorElement.inlineElement {} .embeddedOutputsErrorElement.rightPaneElement {} \/* Styling that is common to warnings and errors is in diagnosticOutput.css *\/.embeddedOutputsWarningElement{    min-height: 18px;    max-height: 250px;    overflow: auto;} .embeddedOutputsWarningElement.inlineElement {} .embeddedOutputsWarningElement.rightPaneElement {} \/* Copyright 2015-2019 The MathWorks, Inc. *\/\/* In this file, styles are not scoped to rtcContainer since they could be in the Dojo Tooltip *\/.diagnosticMessage-wrapper {    font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;    font-size: 12px;} .diagnosticMessage-wrapper.diagnosticMessage-warningType {    color: rgb(255,100,0);} .diagnosticMessage-wrapper.diagnosticMessage-warningType a {    color: rgb(255,100,0);    text-decoration: underline;} .diagnosticMessage-wrapper.diagnosticMessage-errorType {    color: rgb(230,0,0);} .diagnosticMessage-wrapper.diagnosticMessage-errorType a {    color: rgb(230,0,0);    text-decoration: underline;} .diagnosticMessage-wrapper .diagnosticMessage-messagePart,.diagnosticMessage-wrapper .diagnosticMessage-causePart {    white-space: pre-wrap;} .diagnosticMessage-wrapper .diagnosticMessage-stackPart {    white-space: pre;} .embeddedOutputsTextElement,.embeddedOutputsVariableStringElement {    white-space: pre;    word-wrap:  initial;    min-height: 18px;    max-height: 250px;    overflow: auto;} .textElement,.rtcDataTipElement .textElement {    padding-top: 3px;} .embeddedOutputsTextElement.inlineElement,.embeddedOutputsVariableStringElement.inlineElement {} .inlineElement .textElement {} .embeddedOutputsTextElement.rightPaneElement,.embeddedOutputsVariableStringElement.rightPaneElement {    min-height: 16px;} .rightPaneElement .textElement {    padding-top: 2px;    padding-left: 9px;} .embeddedOutputsVariableTableElement .ClientViewDiv  table tr {  height: 22px;  white-space: nowrap;} .embeddedOutputsVariableTableElement .ClientViewDiv  table tr td,.embeddedOutputsVariableTableElement .ClientViewDiv  table tr th {  background-color:white;  text-overflow: ellipsis;  font-family: Arial, sans-serif;  font-size: 12px;  overflow : hidden;} .embeddedOutputsVariableTableElement .ClientViewDiv  table tr span {  text-overflow: ellipsis;  padding: 3px;} .embeddedOutputsVariableTableElement .ClientViewDiv  table tr th {    color: rgba(0,0,0,0.5);  padding: 3px;  font-size: 9px;}'; var head = document.head || document.getElementsByTagName('head')[0], style = document.createElement('style'); head.appendChild(style); style.type = 'text\/css'; if (style.styleSheet){ style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); }<\/script>","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/never_use_jpg_03.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>\r\n\r\nNote added 20-Dec-2022: I wrote this post with lossy JPEG in mind. If you work with DICOM data, see Jeff Mather's note in the comments below about the use of lossless JPEG in DICOM.\r\nI have... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2022\/12\/19\/avoid-jpeg-for-image-analysis\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":6140,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/6146"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=6146"}],"version-history":[{"count":5,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/6146\/revisions"}],"predecessor-version":[{"id":6161,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/6146\/revisions\/6161"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/6140"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=6146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=6146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=6146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}