Changeset 2031
- Timestamp:
- 11/20/07 00:04:32 (6 years ago)
- Location:
- www/study
- Files:
-
- 3 added
- 2 edited
- 2 moved
-
out6-1-1.png (added)
-
out6-1-2.png (moved) (moved from www/study/out6-0-2.png)
-
out6-1-3.png (added)
-
out6-1-4.png (added)
-
out6-1-5.png (moved) (moved from www/study/out6-0-3.png)
-
part6.html (modified) (2 diffs)
-
study.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
www/study/part6.html
r2030 r2031 40 40 of a bigger image. </p> 41 41 42 <p> Since we don’t have many images at our dispos ition, we will simply43 cut Lenna into small chunks and use these parts to create mosaics. This is 44 our <b>image database</b>: </p>42 <p> Since we don’t have many images at our disposal, we will simply cut Lenna 43 into small chunks (called <b>tiles</b>) and use these parts to create mosaics. 44 This is our <b>tile database</b>: </p> 45 45 46 46 <p style="text-align: center;"> … … 49 49 </p> 50 50 51 <p> Here is an example of a simple photographic mosaic method where the 52 original picture is cut into smaller chunks and each chunk is matched to 53 the most resembling item in the image database: </p> 51 <p> Generating a photomosaic consists in subdividing the original picture 52 into <i>x</i> rectangular cells and find <i>x</i> tiles in the database 53 (with or without duplicates, depending on the set of rules that is decided) 54 so that when recombined the resulting image resembles the original picture. 55 By the way, this technique is covered by Runaway Technology Inc’s 56 <a href="http://www.freepatentsonline.com/6137498.html">U.S. patent 57 6137498</a>. </p> 58 59 <p> Picking the right tile for the right cell in the grid is a very 60 expensive and complicated operation. One of the biggest problems is the 61 cost of a database lookup: comparing each tile area pixel-by-pixel 62 is an O(N) operation where N is the size of the database. We can resort 63 to <b>image classification</b> in order to speed up database lookups. </p> 64 65 <h3> 6.1. Image classification </h3> 66 67 <p> One of the simplest image classification technique is the storage of 68 each tile’s <b>average colour</b> into a separate database that is used for 69 best match lookups: </p> 54 70 55 71 <p style="text-align: center;"> 56 <img src="out6-0-2.png" width="80" height="80" 72 <img src="out6-1-1.png" width="168" height="120" 73 class="inline" alt="1 feature extracted from Lenna patterns" /> 74 </p> 75 76 <p> When creating the mosaic, we then only need to check the average colour 77 instead of comparing each pixel one by one. Below is the result of the 78 technique applied on a portion of the Lenna picture: </p> 79 80 <p style="text-align: center;"> 81 <img src="out6-1-2.png" width="80" height="80" 57 82 class="inlinetop" alt="Lenna (detail)" /> 58 <img src="out6-0-3.png" width="416" height="416" 83 <img src="out6-1-3.png" width="416" height="416" 84 class="inline" alt="Mosaic created from Lenna’s detail" /> 85 </p> 86 87 <p> Better results can be achieved by storing <b>four colour values</b>, one 88 for each corner of the tile: </p> 89 90 <p style="text-align: center;"> 91 <img src="out6-1-4.png" width="248" height="176" 92 class="inline" alt="4 features extracted from Lenna patterns" /> 93 </p> 94 95 <p> Having 12 values (4 RGB triplets) is still a lot less than the original 96 value of 3072 (for 32×32 tiles), and the results show clear improvement, 97 for instance the feather-hair frontier is now a lot smoother: </p> 98 99 <p style="text-align: center;"> 100 <img src="out6-1-2.png" width="80" height="80" 101 class="inlinetop" alt="Lenna (detail)" /> 102 <img src="out6-1-5.png" width="416" height="416" 59 103 class="inline" alt="Mosaic created from Lenna’s detail" /> 60 104 </p> -
www/study/study.py
r2030 r2031 39 39 c = self.colorResolve((r, g, b)) 40 40 self.setPixel((x, y), c) 41 def getCrop(self, x, y, w, h): 42 dest = Image((w, h), True) 43 self.copyTo(dest, (-x, -y)) 44 return dest 41 45 42 46 # Manipulate gamma values … … 838 842 return coeffs 839 843 840 def test603(src, sqw, sqh, tnlist, coeffs, dx, dy): 841 (w, h) = src.size() 844 def test601(tnlist, cols): 842 845 (tnw, tnh) = tnlist[0].size() 846 dw = cols 847 dh = (len(tnlist) + cols - 1) / cols 848 dest = Image((dw * tnw + 8 * (dw + 1), dh * tnh + 8 * (dh + 1)), True) 849 for (n, img) in enumerate(tnlist): 850 di = 8 + (n % dw) * (tnw + 8) 851 dj = 8 + (n / dw) * (tnh + 8) 852 for y in range(tnh): 853 for x in range(tnw): 854 (r, g, b) = img.getRgb(x, y) 855 dest.setRgb(di + x, dj + y, r, g, b) 856 return dest 857 858 if chapter(6): 859 tnlist = mosaic_split(lenna256, 32, 32) 860 test601(tnlist, 10).save("out6-0-1.png") 861 862 # Output 6.1.1: extract 1 colour feature from mosaic tiles 863 # Output 6.1.2: crop Lenna 864 # Output 6.1.3: generate a mosaic from the 1-feature database 865 # Output 6.1.4: extract 4 colour features from mosaic tiles 866 # Output 6.1.5: generate a mosaic from the 4-feature database 867 def test61x(coeffs, cols, tnw, tnh): 868 dx = len(coeffs[0][0]) 869 dy = len(coeffs[0]) 870 dw = cols 871 dh = (len(coeffs) + cols - 1) / cols 872 dest = Image((dw * tnw + 8 * (dw + 1), dh * tnh + 8 * (dh + 1)), True) 873 for (n, tab) in enumerate(coeffs): 874 di = 8 + (n % dw) * (tnw + 8) 875 dj = 8 + (n / dw) * (tnh + 8) 876 for y in range(tnh): 877 for x in range(tnw): 878 (r, g, b) = tab[y * dy / tnh][x * dx / tnw] 879 dest.setRgb(di + x, dj + y, Gamma.ItoC(r), Gamma.ItoC(g), Gamma.ItoC(b)) 880 return dest 881 882 def test61y(src, sqw, sqh, tnlist, coeffs): 883 (w, h) = src.size() 884 (tnw, tnh) = tnlist[0].size() 885 dx = len(coeffs[0][0]) 886 dy = len(coeffs[0]) 843 887 nx = w / sqw 844 888 ny = h / sqh … … 873 917 return dest 874 918 875 def test602(src, x, y, w, h):876 dest = Image((w, h), True)877 src.copyTo(dest, (-x, -y))878 return dest879 880 def test601(tnlist, cols):881 (tnw, tnh) = tnlist[0].size()882 dw = cols883 dh = (len(tnlist) + cols - 1) / cols884 dest = Image((dw * tnw + 8 * (dw + 1), dh * tnh + 8 * (dh + 1)), True)885 for (n, img) in enumerate(tnlist):886 di = 8 + (n % dw) * (tnw + 8)887 dj = 8 + (n / dw) * (tnh + 8)888 for y in range(tnh):889 for x in range(tnw):890 (r, g, b) = img.getRgb(x, y)891 dest.setRgb(di + x, dj + y, r, g, b)892 return dest893 894 919 if chapter(6): 895 tnlist = mosaic_split(lenna256, 32, 32) 896 coeffs = mosaic_analyse(tnlist, 2, 2) 897 test601(tnlist, 10).save("out6-0-1.png") 898 out602 = test602(lenna256, 100, 90, 80, 80) 899 out602.save("out6-0-2.png") 900 test603(out602, 6, 6, tnlist, coeffs, 2, 2).save("out6-0-3.png") 920 coeffs1x1 = mosaic_analyse(tnlist, 1, 1) 921 test61x(coeffs1x1, 10, 8, 8).save("out6-1-1.png") 922 out612 = lenna256.getCrop(100, 90, 80, 80) 923 out612.save("out6-1-2.png") 924 test61y(out612, 6, 6, tnlist, coeffs1x1).save("out6-1-3.png") 925 926 coeffs2x2 = mosaic_analyse(tnlist, 2, 2) 927 test61x(coeffs2x2, 10, 16, 16).save("out6-1-4.png") 928 test61y(out612, 6, 6, tnlist, coeffs2x2).save("out6-1-5.png") 901 929 902 930 ##############################################################################
Note: See TracChangeset
for help on using the changeset viewer.
