Shroud of Turin Banding Patterns
Adam Hollenberg
May 5, 2006
Table of
Contents
1. Introducing the Shroud Image ...3
2. Focus: Using Image Processing to Analyze Images of the Shroud ...4
3. General Illustration of Matlab Capabilities ...5
4. Initial Shroud Image Analysis ...9
5. Algorithm Development ..12
6. Algorithm 1 ..12
7. Algorithm 2 ..15
8. Conclusions ..18
9. Suggestions for Farther Investigation ..19
Appendix A: Investigating the Effect of Compression 21
Appendix B: Algorithm 1 22
Appendix C: Algorithm 2 24
Shroud of Turin Banding Patterns
Since its appearance in the late thirteenth century, the Shroud of Turin has sparked much interest and controversy. Believed by some to be the burial shroud of Jesus Christ, the relic has been subject to much analysis and adoration. Most of this attention had subsided in by the late nineteenth century, when the shrouds modern history really begins.
Introducing the Shroud Image
Until the first photographs of the shroud were taken, there was very little evidence to prove or disprove the shrouds authenticity. In 1898, Secundo Pia was the first person to do just that. Since these first photographs, few people have been permitted to closely examine or photograph the shroud. Other dates of interest can be found in the timeline below:

Figure 1: Historical Timeline of Shroud Images
The main purpose of this information is simply to provide a general understanding of where the images of the shroud came from and introduce the reasons that it has been the subject of so much examination. For more information about the shroud and its history, visit some of the following resources:
2. Focus: Using Image Processing to Analyze Images of the
Shroud
While the majority of the discussion surrounding the shroud has been directed towards the authenticity of the shroud, the purpose of this investigation is to analyze the image solely as an image. It will not try to produce evidence of the shrouds authenticity or forgery. This investigation is of a preliminary nature which can be expanded by those who follow however they choose.
The goals of the investigation are to demonstrate that image processing capabilities of Matlab and to use them to identify banding patterns in the shroud image. The image used for this investigation is a cropped image taken from one of the photographs. The image is cropped to the face as to reduce the image size and consequently, processing time.

Figure 2: TIF file of the cropped photograph.
3. General Illustration of Matlab Capabilities
Matlab is a powerful language with a variety of toolboxes available to extend Matlabs capabilities. The image processing toolbox proved to be extremely useful in the analysis of the shroud image. To become more familiar with both the image and the toolbox, a few simple examinations were performed on the image.
First, a comparison between a TIF version and JPEG of the image was
done. To do this, a simple subtraction was performed. Normally, this would
entail a looping process to subtract each pixel in one image from the
corresponding pixel in the other. While not overly complicated, this process
does present opportunity for programmer error. The Matlab image toolbox provides
a command called imsubtract() to
handle the image subtraction. After loading the images into arrays with the imread() command, all that needs to be
done is to pass the names of the arrays into imsubtract and store the result into its own array (see Appendix A
for code). The main feature of the toolbox, imtool,
can then be used to analyze and modify the result. In the case of the shroud
image, the difference image looked essentially black, leading one to believe
that there was no difference between the TIF and JPG files. Using pixel region feature of the imtool, it was discovered that the image
was not all black. In fact, once zoomed in far enough, the RGB (Red, Green, and
Blue) values were displayed for each pixel (ranging from 0 to 255). The
majority of the pixels had at least some value for each. In some of the pixels
with higher values, especially blue, the pixel was visibly pigmented. To test
and make sure that the RGB values of the difference image are accurate, all
that needs to be done is to add the image back to the JPG image and compare the
result with the TIF image. As expected, the two were identical. Without the
image toolbox, it would take a lot of coding and processing time to come up
with the simple conclusion that while JPG files do lose some accuracy through compression,
they do maintain a high level of integrity while highly reducing the file size.
The pixel region feature is extremely
useful for zooming in on a small area to closely examining the RGB values of an
image. In Matlab, imread stores
information on a pixel by pixel basis, meaning that the file type does not
impact the array size. As a result, it is just as easy to work with the TIF
file as it is to work with the JPG because the two arrays are exactly the same
size.
Figure 4: The pixel region of a portion of
the difference image (TIF - JPG).
Another feature of imtool involves the ability to adjust the contrast of an image. This feature only appears to work with grayscale images, so is limited in its functionality as it pertains to this investigation of the shroud. It is still worth mentioning, however, because it allows for easy manipulation of an image. In a matter of a few minutes, the contrast can be enhanced or reduced to produce meaningful changes to an image for farther analysis. The RGB shroud image can painlessly be converted to a grayscale image by using the command, rgb2gray() in the following manner:
Img2 =
rgb2gray(img);
where Img2 is the grayscale image and img is the original RGB image. The image can now be examined using the adjust contrast feature of imtool.

Figure 2: The grayscale conversion of the TIF image.


Figure 3:
(Left) Grayscale image after changing the contrast. (Above) The Adjust Contrast
Tool.
4. Initial Shroud Image Analysis

Figure 6: Blue, Green, and Red values (respectively) displayed independently of one another.
Before developing an algorithm to attempt to draw out the banding in the image, it is valuable to breakdown the image by examining the images properties and becoming familiar with the image. The most effective way to accomplish a better understanding of the image is to look more closely at the RGB properties of the image. The most basic operation is to simple pull out the individual red, green, and blue values and display them independently of one another. It can be determined from the three images that all three colors have strong values throughout the image. This demonstrates that the image has a very low contrast, as will be discussed later. It can also be inferred that the green values have the most relevant information in the image, because the face appears most clearly in the green data. Likewise, the red values produce the most noise because they exhibit very little of the facial features. By filtering out the red values, a cyan image can be produced that depicts the facial features most clearly.

Figure 7: Cyan image produced by removing the red
values.
When looking at the actual RGB values, the red values tended to have the highest intensity of the three. Combined with the fact that they also seem to contribute the least significant data, it is easy to understand why the original image is so faint. One simple way to make the image more obvious is to reverse the intensities by subtracting them from 256. With this algorithm, the highest intensity color of a given pixel would conversely become the lowest intensity color.

Figure 8: The shroud
image displayed with inverted colors.
The resulting image is recognizably different than the original, even ignoring the color change. The face itself looks different. In fact it looks less ghastly and more human. The first negatives of the image taken by Secundo Pia in 1898 showed a similar affect that was the catalyst of all the analysis that has followed. While the color properties are interesting, deeper analysis is needed to gain better understanding of features of the image.
5. Algorithm Development
As stated previously, the main focus of this investigation was to enhance the banding patterns that are present in the shroud image. To start, a general plan was developed to help guide the algorithm development. It was decided that the best way to enhance the banding was to fade out the facial data while bringing out the bands. Next, it became apparent that the algorithm would need to perform a comparison between the band pixels and the surrounding pixel in order to bring them out, because they appeared to have relatively significant differences in pigmentation from nearby pixels.
6. Algorithm 1


The first algorithm developed aimed to achieve the banding enhancement by subtracting the RGB values for each individual pixel from the average RGB values of the corresponding column and then adding the result to the average RGB values of the whole image. The thought behind the algorithm was that by finding the difference between a pixel and the column, any vertical banding would be detected because it would have a significant difference from the column/row average. Adding that back to the average of the whole image would then display the difference on top of a general background color.

Figure 9: Result of the original algorithm designed to
bring out horizontal banding.
The results, as seen in figure 9, were not quite the desired outcome, but did prove helpful in the development of the next algorithm. The algorithm proved successful in fading out the facial features of the image, but it lacked real noticeable banding as well. It essentially washed out the whole image making it more or less the same color. The cause of the fading effect was determined to be largely due to the fact that the difference was being added back into a universal background color. This seemed to mask the result of taking the difference of the pixels and their respective column/row.
When the same algorithm was applied to the rows to draw out the vertical bands, similar results were produced, as can be seen in figure 10.

Figure 10:
Result of the original algorithm designed to bring out vertical banding.
7. Algorithm 2
The second algorithm is similar to the first in that it still takes the
column/row average and subtracts it from the pixel. The change is made by adding
the result to the average RGB values a rolling average (window) of the next n
columns/rows. In figure 11, the window is displayed as a rectangle moving
across the image. 


Figure 11: Demonstration of the rolling average
(window) as it moves across the image.
The results of the second algorithm were noticeably improved over the results of the first. The horizontal bands are much more perceptible in this image than they were in the image resulting from algorithm 1. The features of the face are blended into the background while the horizontal bands are made more obvious. In figure 12, a rolling average of 10 columns was used, which seemed to produce the best results.
.
Figure 12: Horizontal Banding as a result of algorithm
2.
While the second algorithm is a clear improvement over the first, it still did not produce the glaringly obvious results that are desired in this investigation. The same is true of the vertical banding, as can be seen in figure 13. Again, the results are visibly better than algorithm 1, but lack real definition.

Figure 13: Vertical banding produced from algorithm 2.
8. Conclusions
After the results of algorithm 2, several conclusions can be made about the image and this investigation. First, there can be little doubt that the image possesses both vertical and horizontal banding. Second, Matlabs Image Toolbox proved to be a very useful and powerful resource for engaging in processing of the shroud image. Without its high-level interface, much of this investigation would not have been completed as quickly as it was. Also, the second algorithm developed in this investigation shows a lot of promise for leading to the desired results of really bringing out the bands. With this in mind, it is worth noting why the second algorithm may have fallen short of its goals.
One of the major obstacles for the algorithm is the fact that the contrast of the image is so low. Every pixel in the entire image is relatively close to the same color, making it extremely difficult to enhance any particular area above the rest of the image. Also, it is possible that a shortcoming of the algorithm lays in the fact that the window spans the entire length/width of the image. The banding would most likely show up more dramatically if each pixel was compared with a small range of pixels surrounding it.
As mentioned at the beginning of this discussion, this investigation is preliminary in nature and is by no means complete. The goal was to develop a starting point, a place for future investigations to branch off from. Therefore, the investigation would not be complete if it did not include some suggestions about where to go from here.
9. Suggestions for Farther Investigation
First, I would highly recommend that any future investigations continue to use Matlabs Image Processing Toolbox if possible. The manual is very helpful in explaining the capabilities of the tool and will save a lot of time and energy in the long run.
Next, very little of value will be produced unless an algorithm which expands the range of contrast is developed. Expanding the contrast around the same mean will help to make any difference areas (i.e. banding) stand out more. Figure 14 demonstrates the desired effect of contrast adjustment.

Figure 14: Proposed contrast adjustment algorithm.
The next suggestion is to apply Algorithm 2 to an image which has been run through the contrast adjustment algorithm mentioned above. With a higher contrast image, the second algorithm should produce more dramatic results.
If a contrast algorithm presents a problem, an alternative is to use a grayscale version of the image and adjust the contrast with imtool then format Algorithm 2 to work for a grayscale image. It may be worthwhile to perform these actions anyway as a predecessor to the contrast algorithm to get an idea of about how much the contrast will need to be adjusted.
Finally, it will most likely become necessary to take the second algorithm presented in this investigation and create a new one. It is highly unlikely that in this preliminary investigation, the best algorithm has been discovered. The next algorithm will likely need to tighten the windowing idea and perhaps make some other changes that are not perceivable at this point.
The shroud image possesses some fascinating properties that deserve investigation. In the not to distant future, it would not be surprising if some fascinating information about the shroud banding is discovered. Authentic or not, the shroud remains a mysterious artifact and will continue to capture the attention of researchers worldwide.
Appendix A:
Investigating the Effect of Compression
% Subtract a JPG image from a TIF image to find how compression affects the
% individual pixel values.
LargeImage = imread('J:\CSCI490-SI-Process\z-all\shroud\FACEPOS.tif');
SmallImage = imread('J:\CSCI490-SI-Process\z-all\shroud\FACEPOS47.jpg');
Result = imsubtract(LargeImage,SmallImage);
% Analyze the image using the Image Tool. Look at the 'Pixel Region'
% feature to see RGB values of the subtracted image.
imtool(Result)
% Reconstruct the original image by adding the result back to the JPG
% image.
Original = imadd(Result,SmallImage);
imshow(Original)
title('Reconstructed Image')
Appendix B: Algorithm 1
Horizontal Banding
clear Bavg Gavg Ravg;
img = imread('J:\CSCI490-SI-Process\z-all\shroud\FACEPOS.tif');
figure; imshow(img)
% find average RGB values for each column of pixels.
for i = 1:2269
Ravg(1,i) = round(mean(img(i,:,1)));
Gavg(1,i) = round(mean(img(i,:,2)));
Bavg(1,i) = round(mean(img(i,:,3)));
end
Rwhole = 0;
Gwhole = 0;
Bwhole = 0;
% find average RGB values over whole image.
for i = 1:2269
Rwhole = Rwhole + round(mean(img(i,:,1)));
Gwhole = Gwhole + round(mean(img(i,:,2)));
Bwhole = Bwhole + round(mean(img(i,:,3)));
end
Rwhole = round(Rwhole/2269);
Gwhole = round(Gwhole/2269);
Bwhole = round(Bwhole/2269);
% recreate image by subtracting RGB values of each pixel from the average
% RGB values of the column and adding the result to the average RGB values
% for the whole image.
for i = 1:2269
for j = 1:1631
img2(i,j,1) = img(i,j,1) - Ravg(1,i) + Rwhole;
img2(i,j,2) = img(i,j,2) - Gavg(1,i) + Gwhole;
img2(i,j,3) = img(i,j,3) - Bavg(1,i) + Bwhole;
end
end
figure; imshow(img2)
Vertical Banding
clear Bavg Gavg Ravg;
img = imread('J:\CSCI490-SI-Process\z-all\shroud\FACEPOS.tif');
figure; imshow(img)
% find average RGB values for each row of pixels.
for i = 1:1631
Ravg(1,i) = round(mean(img(:,i,1)));
Gavg(1,i) = round(mean(img(:,i,2)));
Bavg(1,i) = round(mean(img(:,i,3)));
end
% find average RGB values over whole image.
Rwhole = 0;
Gwhole = 0;
Bwhole = 0;
for i = 1:1631
Rwhole = Rwhole + round(mean(img(:,i,1)));
Gwhole = Gwhole + round(mean(img(:,i,2)));
Bwhole = Bwhole + round(mean(img(:,i,3)));
end
Rwhole = round(Rwhole/1631);
Gwhole = round(Gwhole/1631);
Bwhole = round(Bwhole/1631);
% recreate image by subtracting RGB values of each pixel from the average
% RGB values of the row and adding the result to the average RGB values
% for the whole image.
for j = 1:1631
for i = 1:2269
img4(i,j,1) = img(i,j,1) - Ravg(1,j) + Rwhole;
img4(i,j,2) = img(i,j,2) - Gavg(1,j) + Gwhole;
img4(i,j,3) = img(i,j,3) - Bavg(1,j) + Bwhole;
end
end
figure; imshow(img4)
Appendix C: Algorithm 2
Horizontal Banding
clear Bavg Gavg Ravg;
img = imread('J:\CSCI490-SI-Process\z-all\shroud\FACEPOS.tif');
figure; imshow(img)
% find average RGB values for each column of pixels.
for i = 1:2269
Ravg(1,i) = round(mean(img(i,:,1)));
Gavg(1,i) = round(mean(img(i,:,2)));
Bavg(1,i) = round(mean(img(i,:,3)));
end
Rwhole = 0;
Gwhole = 0;
Bwhole = 0;
% find average RGB values over whole image.
for i = 1:2269
Rwhole = Rwhole + round(mean(img(i,:,1)));
Gwhole = Gwhole + round(mean(img(i,:,2)));
Bwhole = Bwhole + round(mean(img(i,:,3)));
end
Rwhole = round(Rwhole/2269);
Gwhole = round(Gwhole/2269);
Bwhole = round(Bwhole/2269);
% recreate image by subtracting RGB values of each pixel from the average
% RGB values of the column and adding the result to a rolling average of
% the next n columns.
integ = 10;
for i = 1:2269-(integ)
Rint = round(mean(Ravg(1,i:(i+integ))));
Gint = round(mean(Gavg(1,i:(i+integ))));
Bint = round(mean(Bavg(1,i:(i+integ))));
for j = 1:1631
img3(i,j,1) = img(i,j,1) - Ravg(1,i) + Rint;
img3(i,j,2) = img(i,j,2) - Gavg(1,i) + Gint;
img3(i,j,3) = img(i,j,3) - Bavg(1,i) + Bint;
end
end
figure; imshow(img3)
Vertical Banding
clear Bavg Gavg Ravg;
img = imread('J:\CSCI490-SI-Process\z-all\shroud\FACEPOS.tif');
figure; imshow(img)
%{
% find average RGB values for each row of pixels.
for i = 1:1631
Ravg(1,i) = round(mean(img(:,i,1)));
Gavg(1,i) = round(mean(img(:,i,2)));
Bavg(1,i) = round(mean(img(:,i,3)));
end
%}
% find average RGB values over whole image.
Rwhole = 0;
Gwhole = 0;
Bwhole = 0;
for i = 1:1631
Rwhole = Rwhole + round(mean(img(:,i,1)));
Gwhole = Gwhole + round(mean(img(:,i,2)));
Bwhole = Bwhole + round(mean(img(:,i,3)));
end
Rwhole = round(Rwhole/1631);
Gwhole = round(Gwhole/1631);
Bwhole = round(Bwhole/1631);
% recreate image by subtracting RGB values of each pixel from the average
% RGB values of the row and adding the result to the average RGB values
% a rolling average of the next n columns.
integ = 10;
for i = 1:1631-(integ)
Rint = round(mean(Ravg(1,i:(i+integ))));
Gint = round(mean(Gavg(1,i:(i+integ))));
Bint = round(mean(Bavg(1,i:(i+integ))));
for j = 1:2269
img5(j,i,1) = img(j,i,1) - Ravg(1,i) + Rint;
img5(j,i,2) = img(j,i,2) - Gavg(1,i) + Gint;
img5(j,i,3) = img(j,i,3) - Bavg(1,i) + Bint;
end
end
figure; imshow(img5)