├── Dctlab ├── DCTlab.png ├── DCTlabDefaults.txt ├── Hdefault.txt ├── LICENSE ├── Qdefault.txt ├── Qtable2.txt ├── README.md ├── Zdefault.txt ├── blkdct2cos.m ├── blkdct2fft.m ├── blkidct2cos.m ├── blkidct2fft.m ├── dct2sq.m ├── dct_8x8_basis.png ├── dctact.m ├── dctbasis.m ├── dctlab.m └── idct2sq.m ├── JSCCImage ├── AWGN1_RCPC.png ├── BSC_BER.m ├── GE_awgn.m ├── LICENSE ├── Punct_Variables.m ├── Punct_codes.txt ├── RCPC_ch_epsilon.png ├── RCPC_ch_ro.png ├── RCPC_decode.m ├── RCPC_encode.m ├── RCPC_performance │ ├── RCPC_performance_10000x250.mat │ ├── RCPC_performance_AWGN1.mat │ ├── RCPC_performance_AWGN2.mat │ ├── RCPC_performance_BSC1.mat │ ├── RCPC_performance_GE1.mat │ └── info.txt ├── RCPC_test_equal_data.m ├── RCPC_test_equal_packet.m ├── RD_curve │ ├── Lena256RD.mat │ └── info.txt ├── RDcurveBytePrec.m ├── README.md ├── awgn_EsN0.m ├── channels │ ├── AWGN1.txt │ ├── AWGN2.txt │ ├── AWGN_0dB.txt │ ├── BSC1.txt │ └── GE1.txt ├── compute_gain.m ├── generic_crc.m ├── get_RCPC_code.m ├── get_channel.m ├── optimal_RCPC_RS_equal.m ├── optimal_RCPC_equal.m ├── optimal_RCPC_unequal.m ├── probMSE2phi.m ├── script_RCPC_performance.m ├── script_channel_performance.m ├── script_send_image_RCPC.m ├── send_image_equal.m ├── send_image_equal_RS.m └── send_image_unequal.m ├── Jpeg2000 ├── Jpeg2000gui.png ├── LICENSE ├── README.md ├── jpeg2000gui.fig ├── jpeg2000gui.m ├── jpeg2000jj2k.m ├── jpeg2000kakadu.m └── jpeg2000kakadu_yuv.m ├── QualityAssessment ├── LICENSE ├── README.md ├── image_show.m └── iq_measures.m ├── Wavelet ├── 2Dwavelet.png ├── CDF_9x7_scaling_analysis.png ├── LICENSE ├── LeGall_5x3_h0.png ├── Lena_transform_coefficients.jpg ├── README.md ├── Wavelets │ ├── Burt_5x7.wvf │ ├── CDF_9x7.wvf │ ├── Haar.wvf │ ├── Haar_deltalp.wvf │ ├── LeGall_5x3.wvf │ └── LeGall_5x3_deltalp.wvf ├── bibo_gains.m ├── decomp_packets2D.m ├── draw_packets.m ├── dwt_2D.m ├── dwt_conv1D.m ├── dwt_dim.m ├── dwt_dyadic_decomp.m ├── dwt_lifting1D.m ├── filt2lift.m ├── idwt_2D.m ├── idwt_conv1D.m ├── idwt_dim.m ├── idwt_dyadic_recon.m ├── idwt_lifting1D.m ├── load_wavelet.m ├── recon_packets2D.m ├── scaling_fun.m ├── subband.m ├── subband_dim.m ├── submatrix.m ├── wavelet2D.m ├── wavelet_9x7_char_freq.png ├── wavelet_9x7_char_phase.png ├── wavelet_char.m ├── wavelet_check.m ├── wavelet_downscale.m ├── wavelet_fun.m └── wavelet_packet_subband_tree.png ├── YUV ├── BT601_219.mat ├── BT601_f.mat ├── BT601_l.mat ├── BT709_f.mat ├── BT709_l.mat ├── LICENSE ├── README.md ├── SMPTE_240M.mat ├── TODO ├── divide_seq.m ├── mm2yuv.m ├── read_floatframe.m ├── rgb2yuv.m ├── save_yuvframe.m ├── scale_seq.m ├── seq_frames.m ├── shift_seq.m ├── write_floatframe.m ├── yuv2avi.m ├── yuv2avi_demosaic.m ├── yuv2rgb.m ├── yuv2seq_demosaic.m ├── yuv_compare.m ├── yuv_export.m ├── yuv_import.m └── yuv_range.m ├── ZerotreeCoding ├── LICENSE ├── README.md ├── SPIHT_flowchart.png ├── dead_zone_q.m ├── ezw.m ├── ezw_testdata1.mat ├── ezw_testdata2.mat ├── pdf_opt.m ├── spiht_stream_dec.m ├── spiht_wpackets.m └── spspiht.m └── setpaths.m /Dctlab/DCTlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Dctlab/DCTlab.png -------------------------------------------------------------------------------- /Dctlab/DCTlabDefaults.txt: -------------------------------------------------------------------------------- 1 | quantization=Qdefault.txt 2 | zig-zag=Zdefault.txt 3 | Huffman=Hdefault.txt -------------------------------------------------------------------------------- /Dctlab/Hdefault.txt: -------------------------------------------------------------------------------- 1 | DC 12 2 | 0,2,00 3 | 1,3,010 4 | 2,3,011 5 | 3,3,100 6 | 4,3,101 7 | 5,3,110 8 | 6,4,1110 9 | 7,5,11110 10 | 8,6,111110 11 | 9,7,1111110 12 | 10,8,11111110 13 | 11,9,111111110 14 | AC 162 15 | 0/0,4,1010 16 | 0/1,2,00 17 | 0/2,2,01 18 | 0/3,3,100 19 | 0/4,4,1011 20 | 0/5,5,11010 21 | 0/6,7,1111000 22 | 0/7,8,11111000 23 | 0/8,10,1111110110 24 | 0/9,16,1111111110000010 25 | 0/A,16,1111111110000011 26 | 1/1,4,1100 27 | 1/2,5,11011 28 | 1/3,7,1111001 29 | 1/4,9,111110110 30 | 1/5,11,11111110110 31 | 1/6,16,1111111110000100 32 | 1/7,16,1111111110000101 33 | 1/8,16,1111111110000110 34 | 1/9,16,1111111110000111 35 | 1/A,16,1111111110001000 36 | 2/1,5,11100 37 | 2/2,8,11111001 38 | 2/3,10,1111110111 39 | 2/4,12,111111110100 40 | 2/5,16,1111111110001001 41 | 2/6,16,1111111110001010 42 | 2/7,16,1111111110001011 43 | 2/8,16,1111111110001100 44 | 2/9,16,1111111110001101 45 | 2/A,16,1111111110001110 46 | 3/1,6,111010 47 | 3/2,9,111110111 48 | 3/3,12,111111110101 49 | 3/4,16,1111111110001111 50 | 3/5,16,1111111110010000 51 | 3/6,16,1111111110010001 52 | 3/7,16,1111111110010010 53 | 3/8,16,1111111110010011 54 | 3/9,16,1111111110010100 55 | 3/A,16,1111111110010101 56 | 4/1,6,111011 57 | 4/2,10,1111111000 58 | 4/3,16,1111111110010110 59 | 4/4,16,1111111110010111 60 | 4/5,16,1111111110011000 61 | 4/6,16,1111111110011001 62 | 4/7,16,1111111110011010 63 | 4/8,16,1111111110011011 64 | 4/9,16,1111111110011100 65 | 4/A,16,1111111110011101 66 | 5/1,7,1111010 67 | 5/2,11,11111110111 68 | 5/3,16,1111111110011110 69 | 5/4,16,1111111110011111 70 | 5/5,16,1111111110100000 71 | 5/6,16,1111111110100001 72 | 5/7,16,1111111110100010 73 | 5/8,16,1111111110100011 74 | 5/9,16,1111111110100100 75 | 5/A,16,1111111110100101 76 | 6/1,7,1111011 77 | 6/2,12,111111110110 78 | 6/3,16,1111111110100110 79 | 6/4,16,1111111110100111 80 | 6/5,16,1111111110101000 81 | 6/6,16,1111111110101001 82 | 6/7,16,1111111110101010 83 | 6/8,16,1111111110101011 84 | 6/9,16,1111111110101100 85 | 6/A,16,1111111110101101 86 | 7/1,8,11111010 87 | 7/2,12,111111110111 88 | 7/3,16,1111111110101110 89 | 7/4,16,1111111110101111 90 | 7/5,16,1111111110110000 91 | 7/6,16,1111111110110001 92 | 7/7,16,1111111110110010 93 | 7/8,16,1111111110110011 94 | 7/9,16,1111111110110100 95 | 7/A,16,1111111110110101 96 | 8/1,9,111111000 97 | 8/2,15,111111111000000 98 | 8/3,16,1111111110110110 99 | 8/4,16,1111111110110111 100 | 8/5,16,1111111110111000 101 | 8/6,16,1111111110111001 102 | 8/7,16,1111111110111010 103 | 8/8,16,1111111110111011 104 | 8/9,16,1111111110111100 105 | 8/A,16,1111111110111101 106 | 9/1,9,11111101 107 | 9/2,16,1111111110111110 108 | 9/3,16,1111111110111111 109 | 9/4,16,1111111111000000 110 | 9/5,16,1111111111000001 111 | 9/6,16,1111111111000010 112 | 9/7,16,1111111111000011 113 | 9/8,16,1111111111000100 114 | 9/9,16,1111111111000101 115 | 9/A,16,1111111111000110 116 | A/1,9,111111010 117 | A/2,16,1111111111000111 118 | A/3,16,1111111111001000 119 | A/4,16,1111111111001001 120 | A/5,16,1111111111001010 121 | A/6,16,1111111111001011 122 | A/7,16,1111111111001100 123 | A/8,16,1111111111001101 124 | A/9,16,1111111111001110 125 | A/A,16,1111111111001111 126 | B/1,10,1111111001 127 | B/2,16,1111111111010000 128 | B/3,16,1111111111010001 129 | B/4,16,1111111111010010 130 | B/5,16,1111111111010011 131 | B/6,16,1111111111010100 132 | B/7,16,1111111111010101 133 | B/8,16,1111111111010110 134 | B/9,16,1111111111010111 135 | B/A,16,1111111111011000 136 | C/1,10,1111111010 137 | C/2,16,1111111111011001 138 | C/3,16,1111111111011010 139 | C/4,16,1111111111011011 140 | C/5,16,1111111111011100 141 | C/6,16,1111111111011101 142 | C/7,16,1111111111011110 143 | C/8,16,1111111111011111 144 | C/9,16,1111111111100000 145 | C/A,16,1111111111100001 146 | D/1,11,11111111000 147 | D/2,16,1111111111100010 148 | D/3,16,1111111111100011 149 | D/4,16,1111111111100100 150 | D/5,16,1111111111100101 151 | D/6,16,1111111111100110 152 | D/7,16,1111111111100111 153 | D/8,16,1111111111101000 154 | D/9,16,1111111111101001 155 | D/A,16,1111111111101010 156 | E/1,16,1111111111101011 157 | E/2,16,1111111111101100 158 | E/3,16,1111111111101101 159 | E/4,16,1111111111101110 160 | E/5,16,1111111111101111 161 | E/6,16,1111111111110000 162 | E/7,16,1111111111110001 163 | E/8,16,1111111111110010 164 | E/9,16,1111111111110011 165 | E/A,16,1111111111110100 166 | F/0,11,11111111001 167 | F/1,16,1111111111110101 168 | F/2,16,1111111111110110 169 | F/3,16,1111111111110111 170 | F/4,16,1111111111111000 171 | F/5,16,1111111111111001 172 | F/6,16,1111111111111010 173 | F/7,16,1111111111111011 174 | F/8,16,1111111111111100 175 | F/9,16,1111111111111101 176 | F/A,16,1111111111111110 177 | -------------------------------------------------------------------------------- /Dctlab/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Nikola Sprljan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Dctlab/Qdefault.txt: -------------------------------------------------------------------------------- 1 | 1.6000000e+001 1.1000000e+001 1.0000000e+001 1.6000000e+001 2.4000000e+001 4.0000000e+001 5.1000000e+001 6.1000000e+001 2 | 1.2000000e+001 1.2000000e+001 1.4000000e+001 1.9000000e+001 2.6000000e+001 5.8000000e+001 6.0000000e+001 5.5000000e+001 3 | 1.4000000e+001 1.3000000e+001 1.6000000e+001 2.4000000e+001 4.0000000e+001 5.7000000e+001 6.9000000e+001 5.6000000e+001 4 | 1.4000000e+001 1.7000000e+001 2.2000000e+001 2.9000000e+001 5.1000000e+001 8.7000000e+001 8.0000000e+001 6.2000000e+001 5 | 1.8000000e+001 2.2000000e+001 3.7000000e+001 5.6000000e+001 6.8000000e+001 1.0900000e+002 1.0300000e+002 7.7000000e+001 6 | 2.4000000e+001 3.5000000e+001 5.5000000e+001 6.4000000e+001 8.1000000e+001 1.0400000e+002 1.1300000e+002 9.2000000e+001 7 | 4.9000000e+001 6.4000000e+001 7.8000000e+001 8.7000000e+001 1.0300000e+002 1.2100000e+002 1.2000000e+002 1.0100000e+002 8 | 7.2000000e+001 9.2000000e+001 9.5000000e+001 9.8000000e+001 1.1200000e+002 1.0000000e+002 1.0300000e+002 9.9000000e+001 9 | -------------------------------------------------------------------------------- /Dctlab/Qtable2.txt: -------------------------------------------------------------------------------- 1 | 5.0000000e+000 8.0000000e+000 1.3000000e+001 2.0000000e+001 2.9000000e+001 4.0000000e+001 5.3000000e+001 6.8000000e+001 2 | 8.0000000e+000 1.1000000e+001 1.6000000e+001 2.3000000e+001 3.2000000e+001 4.3000000e+001 5.6000000e+001 7.1000000e+001 3 | 1.3000000e+001 1.6000000e+001 2.1000000e+001 2.8000000e+001 3.7000000e+001 4.8000000e+001 6.1000000e+001 7.6000000e+001 4 | 2.0000000e+001 2.3000000e+001 2.8000000e+001 3.5000000e+001 4.4000000e+001 5.5000000e+001 6.8000000e+001 8.3000000e+001 5 | 2.9000000e+001 3.2000000e+001 3.7000000e+001 4.4000000e+001 5.3000000e+001 6.4000000e+001 7.7000000e+001 9.2000000e+001 6 | 4.0000000e+001 4.3000000e+001 4.8000000e+001 5.5000000e+001 6.4000000e+001 7.5000000e+001 8.8000000e+001 1.0300000e+002 7 | 5.3000000e+001 5.6000000e+001 6.1000000e+001 6.8000000e+001 7.7000000e+001 8.8000000e+001 1.0100000e+002 1.1600000e+002 8 | 6.8000000e+001 7.1000000e+001 7.6000000e+001 8.3000000e+001 9.2000000e+001 1.0300000e+002 1.1600000e+002 1.3100000e+002 9 | -------------------------------------------------------------------------------- /Dctlab/README.md: -------------------------------------------------------------------------------- 1 | DCTlab 2 | ====== 3 | 4 | A GUI for sudying the steps of DCT-based image compression and for assessment of reconstructed image quality. The program window is divided into parts representing stages of JPEG image compression - transform, quantisation, coding. Additional menus are available with right-click over displayed image (e.g. for the original image the choices are: Zoom View (shows enlarged picture), Save (saves picture as .bmp file), Assign to workspace (saves image as a variable in Matlab workspace). 5 | 6 | If the selected size of DCT block is 8x8 (as in JPEG), quantisation table and coding can be applied, leading to the compressed bit-stream. Note that no actual bit-stream is generated, just the resulting bit rate is computed. The compression ratio can be adjusted by changing the quantisation matrix (by multiplying it with a selected constant). Zig-zag scanning order, quantisation matrix and Huffman codes are user-definable. The predefined tables, taken from the JPEG standard, come with DCTlab: Qdefault.txt (quantization matrix), Zdeafult.txt (zig-zag pattern), Hdefault (Huffman tables). The file DCTlabDefaults.txt is a 'registry' file pointing to the files containing these tables, so new ones can easily be added in this way. Supported image formats are greyscale .bmp, .png and .mat, and dimensions are restricted to be powers of two, with a square aspect ratio. 7 | 8 | The main portion of this software was developed during my BSc and MSc studies at the Department of Radiocommunications and Microwave Engineering [Video Communications Laboratory](http://www.vcl.fer.hr/), [Faculty of Electrical Engineering and Computing](http://www.fer.hr/), University of Zagreb. 9 | 10 | Functions 11 | --------- 12 | 13 | - **dctlab** - 2D DCT on blocks (using cosine function), optimised for square matrices 14 | - **blkdct2cos** - 2D DCT on blocks (using cosine function), optimised for square matrices 15 | - **blkdct2fft** - 2D DCT on blocks (using fft), optimised for square matrices 16 | - **blkidct2cos** - 2D IDCT on blocks (using cosine function), optimised for square matrices 17 | - **blkidct2fft** - 2D IDCT on blocks (using fft), optimised for square matrices 18 | - **dct2sq** - 2D DCT optimised for square matrices 19 | - **dctbasis** - Computes the elementary basis functions for 1D and 2D DCT 20 | - **idct2sq** - 2D IDCT optimised for square matrices 21 | 22 | Examples 23 | -------- 24 | **dctlab** screenshot: 25 | 26 | ![dctlab screenshot](https://github.com/nsprljan/ImageCodingResearchTools/raw/master/Dctlab/DCTlab.png) 27 | 28 | DCT basis functions with **dctbasis**: 29 | 30 | >> A=dctbasis(8,2); 31 | 32 | ![DCT 8x8 basis](https://github.com/nsprljan/ImageCodingResearchTools/raw/master/Dctlab/dct_8x8_basis.png) 33 | -------------------------------------------------------------------------------- /Dctlab/Zdefault.txt: -------------------------------------------------------------------------------- 1 | 0.0000000e+000 1.0000000e+000 5.0000000e+000 6.0000000e+000 1.4000000e+001 1.5000000e+001 2.7000000e+001 2.8000000e+001 2 | 2.0000000e+000 4.0000000e+000 7.0000000e+000 1.3000000e+001 1.6000000e+001 2.6000000e+001 2.9000000e+001 4.2000000e+001 3 | 3.0000000e+000 8.0000000e+000 1.2000000e+001 1.7000000e+001 2.5000000e+001 3.0000000e+001 4.1000000e+001 4.3000000e+001 4 | 9.0000000e+000 1.1000000e+001 1.8000000e+001 2.4000000e+001 3.1000000e+001 4.0000000e+001 4.4000000e+001 5.3000000e+001 5 | 1.0000000e+001 1.9000000e+001 2.3000000e+001 3.2000000e+001 3.9000000e+001 4.5000000e+001 5.2000000e+001 5.4000000e+001 6 | 2.0000000e+001 2.2000000e+001 3.3000000e+001 3.8000000e+001 4.6000000e+001 5.1000000e+001 5.5000000e+001 6.0000000e+001 7 | 2.1000000e+001 3.4000000e+001 3.7000000e+001 4.7000000e+001 5.0000000e+001 5.6000000e+001 5.9000000e+001 6.1000000e+001 8 | 3.5000000e+001 3.6000000e+001 4.8000000e+001 4.9000000e+001 5.7000000e+001 5.8000000e+001 6.2000000e+001 6.3000000e+001 9 | -------------------------------------------------------------------------------- /Dctlab/blkdct2cos.m: -------------------------------------------------------------------------------- 1 | function Y=blkdct2cos(X,block) 2 | %Y = blkdct2cos(X,block) 3 | %2D DCT on blocks (using cosine function), optimised for square matrices 4 | % 5 | %Input: 6 | % X - input matrix (must be square as no check is performed) 7 | % block - size of the block on which X will be divided, must be square 8 | % 9 | %Output: 10 | % Y - DCT coefficients matrix, divided in blocks 11 | % 12 | %Note: 13 | % Works faster then 'blkdct2fft' when the blocks are small. 14 | % 15 | %Example: 16 | % Y = blkdct2cos(rand(16),4); 17 | 18 | j1=0:block-1; 19 | j2=0:block-1; 20 | [J1,J2]=meshgrid(j1,j2); 21 | C=cos(((2.*J1+1).*J2*pi)/(block*2)); 22 | D=C'; 23 | X=double(X)./(block/2); 24 | siz=size(X,1); 25 | nblocks=siz/block; 26 | rowscols=1:block; 27 | [rr,cc]=meshgrid(0:(nblocks-1), 0:(nblocks-1)); 28 | rr=rr(:); 29 | cc=cc(:); 30 | Y = zeros(size(X)); 31 | 32 | for k=1:length(rr) 33 | x=X(rr(k)*block+rowscols,cc(k)*block+rowscols); 34 | D1=x*D; 35 | D2=C*D1; 36 | D2(:,1)=D2(:,1).*(1/sqrt(2)); 37 | D2(1,:)=D2(1,:).*(1/sqrt(2)); 38 | Y(rr(k)*block+rowscols,cc(k)*block+rowscols)=D2(rowscols,rowscols); 39 | end; 40 | -------------------------------------------------------------------------------- /Dctlab/blkdct2fft.m: -------------------------------------------------------------------------------- 1 | function Y=blkdct2fft(X, block) 2 | % Y = blkdct2fft(X, block) 3 | %2D DCT on blocks (using fft), optimised for square matrices 4 | % 5 | %Input: 6 | % X - input matrix (must be square as no check is performed) 7 | % block - size of the blocks in which X will be divided, must be square 8 | % 9 | %Output: 10 | % Y - DCT coefficients matrix, divided in blocks 11 | % 12 | %Note: 13 | % Various tweaks introduced. Compare the speed with 'blkproc', especially 14 | % for 2^n sized inputs. Core of the dct2sq.m is used here - take a look at 15 | % the note for dct2sq.m! 16 | % Works faster then 'blkdct2cos' when the blocks are large. 17 | % 18 | %Example: 19 | % Y = blkdct2fft(rand(256),4); 20 | 21 | X = double(X); 22 | siz = size(X,1); 23 | nblocks = siz/block; 24 | rowscols = 1:block; 25 | [rr,cc] = meshgrid(0:(nblocks-1), 0:(nblocks-1)); 26 | rr = rr(:); 27 | cc = cc(:); 28 | ww = 2*exp(-i*(0:block-1)'*pi/(2*block))/sqrt(2*block); 29 | ww(1) = ww(1) / sqrt(2); 30 | W = repmat(ww,[1 block]); 31 | Y = zeros(size(X)); 32 | 33 | for k = 1:length(rr) 34 | x = X(rr(k)*block+rowscols,cc(k)*block+rowscols); 35 | 36 | c = [ x(1,:); x(3:2:block,:); x(block,:); x(block-2:-2:2,:)]; 37 | c = real(W .* fft(c))'; 38 | 39 | d = [ c(1,:); c(3:2:block,:); c(block,:); c(block-2:-2:2,:)]; 40 | d = real(W .* fft(d))'; 41 | 42 | Y(rr(k)*block+rowscols,cc(k)*block+rowscols) = d(rowscols,rowscols); 43 | end; 44 | -------------------------------------------------------------------------------- /Dctlab/blkidct2cos.m: -------------------------------------------------------------------------------- 1 | function X=blkidct2cos(Y,block) 2 | %X = blkidct2cos(Y,block) 3 | %2D IDCT on blocks (using cosine function), optimised for square matrices 4 | % 5 | %Input: 6 | % Y - DCT coefficients matrix (must be square as no check is performed) 7 | % block - size of the blocks in which Y is divided, must be square 8 | % 9 | %Output: 10 | % X - inverse transformed matrix 11 | % 12 | %Note: 13 | % Works faster then 'blkidct2fft' when the blocks are small. 14 | % 15 | %Example: 16 | % X = blkidct2cos(rand(16), 4); 17 | 18 | j1=0:block-1; 19 | j2=0:block-1; 20 | [J1,J2]=meshgrid(j1,j2); 21 | C=cos(((2.*J1+1).*J2*pi)/(block*2)); 22 | D=C'; 23 | Y=double(Y)./(block/2); 24 | siz=size(Y,1); 25 | nblocks=siz/block; 26 | rowscols=1:block; 27 | [rr,cc]=meshgrid(0:(nblocks-1), 0:(nblocks-1)); 28 | rr=rr(:); 29 | cc=cc(:); 30 | X = zeros(size(Y)); 31 | 32 | for k=1:length(rr) 33 | x=Y(rr(k)*block+rowscols,cc(k)*block+rowscols); 34 | x(:,1)=x(:,1).*(1/sqrt(2)); 35 | x(1,:)=x(1,:).*(1/sqrt(2)); 36 | D1=x*C; 37 | D2=D*D1; 38 | X(rr(k)*block+rowscols,cc(k)*block+rowscols)=D2(rowscols,rowscols); 39 | end; 40 | -------------------------------------------------------------------------------- /Dctlab/blkidct2fft.m: -------------------------------------------------------------------------------- 1 | function X=blkidct2fft(Y, block) 2 | % X = blkidct2fft(Y, block) 3 | %2D IDCT on blocks (using fft), optimised for square matrices 4 | % 5 | %Input: 6 | % Y - DCT coefficients matrix (must be square as no check is performed) 7 | % block - size of the blocks in which Y is divided, must be square 8 | % 9 | %Output: 10 | % X - take a look at idct2sq.m for explanation of this output... 11 | % 12 | %Note: 13 | % Take a look at the note for blkdct2fft.m! 14 | % 15 | %Example: 16 | % X = blkidct2fft(rand(256), 64); 17 | 18 | Y = double(Y); 19 | siz = size(Y,1); 20 | nblocks = siz/block; 21 | rowscols = 1:block; 22 | [rr,cc] = meshgrid(0:(nblocks-1), 0:(nblocks-1)); 23 | rr = rr(:); 24 | cc = cc(:); 25 | 26 | ww = sqrt(2*block) * exp(j*(0:block-1)*pi/(2*block)).'; 27 | ww(1) = ww(1)/sqrt(2); 28 | W = repmat(ww,[1 block]); 29 | X = zeros(size(Y)); 30 | 31 | for k = 1:length(rr) 32 | y = Y(rr(k)*block+rowscols,cc(k)*block+rowscols); 33 | 34 | y = real(ifft(W.*y)); 35 | c(1,:) = y(1,:); 36 | c(3:2:block,:) = y(2:block/2,:); 37 | c(2:2:block-2,:) = y(block:-1:block/2+2,:); 38 | c(block,:) = y(block/2+1,:); 39 | c = c'; 40 | 41 | c = real(ifft(W.*c)); 42 | d(1,:) = c(1,:); 43 | d(3:2:block,:) = c(2:block/2,:); 44 | d(2:2:block-2,:) = c(block:-1:block/2+2,:); 45 | d(block,:) = c(block/2+1,:); 46 | d = d'; 47 | 48 | X(rr(k)*block+rowscols,cc(k)*block+rowscols) = d(rowscols,rowscols); 49 | end; 50 | -------------------------------------------------------------------------------- /Dctlab/dct2sq.m: -------------------------------------------------------------------------------- 1 | function Y=dct2sq(X) 2 | %Y = dct2sq(X) 3 | %Version: 3.01, Date: 2008/03/02, author: Nikola Sprljan 4 | %2D DCT optimised for square matrices 5 | % 6 | %Input: 7 | % X - input matrix (must be square as no check is performed) 8 | % 9 | %Output: 10 | % Y - DCT coefficients matrix 11 | % 12 | %Note: 13 | % If the input matrix is of size 2^n x 2^n, the execution can around two 14 | % times faster than the default Matlab's 'dct2' command. The reason is that 15 | % in 'dct2' the line aa = a(1:n,:); gets executed while in this function it 16 | % is not needed (no truncation necessary). n is equal to the number of rows 17 | % (n = size(a,1);), and strangely for n = 2^k the abovementioned line is 18 | % several times slower than for other n. Don't have a clue why. 19 | % 20 | %Example: 21 | % Y = dct2sq(rand(1024)); 22 | 23 | n = size(X,1); 24 | ww = 2*exp(-i*(0:n-1)'*pi/(2*n))/sqrt(2*n); 25 | ww(1) = ww(1) / sqrt(2); 26 | W = repmat(ww,[1 n]); 27 | 28 | Y = dctsq1D(dctsq1D(X,W,n)',W,n)'; 29 | 30 | function b=dctsq1D(aa,W,n) 31 | %y = double([ aa(1:2:n,:); aa(n:-2:2,:) ]); 32 | %rather like this below, to avoid n = 2^k strangeness 33 | y = double([ aa(1,:); aa(3:2:n,:); aa(n,:); aa(n-2:-2:2,:)]); 34 | b = real(W .* fft(y)); 35 | -------------------------------------------------------------------------------- /Dctlab/dct_8x8_basis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Dctlab/dct_8x8_basis.png -------------------------------------------------------------------------------- /Dctlab/dctact.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Dctlab/dctact.m -------------------------------------------------------------------------------- /Dctlab/dctbasis.m: -------------------------------------------------------------------------------- 1 | function A=dctbasis(N,D) 2 | %A = dctbasis(N,D) 3 | %Computes the elementary basis functions for 1D and 2D DCT 4 | % 5 | %Input: 6 | % N - basis size 7 | % D - basis dimension, 1 for 1D, 2 for 2D 8 | % 9 | %Output: 10 | % A - array containing the elementary basis functions 11 | % 12 | %Note: 13 | % For 1D the output array is of size NxN with columns containing the 14 | % elementary functions. 15 | % For 2D the output array is of size NxNxNxN, and the elementary function 16 | % corresponding to (i,j) DCT coefficient can be obtained as A(:,:,i,j) 17 | % 18 | %Example: 19 | % A=dctbasis(8,2); %8x8 DCT basic functions, display it with e.g. 20 | % %image_show(128*(1+A(:,:,2,7)),256,16,'DCT-2-7'); 21 | % A=dctbasis(4,1); %4x1 DCT basic functions 22 | % A=dctbasis(4,2); 23 | 24 | for i=1:8 25 | for j=1:8 26 | image_show(128*(1+A(:,:,i,j)),256,16,[num2str(i-1) 'x' num2str(j-1)]); 27 | end; 28 | end; 29 | 30 | i=0:N-1; 31 | j=0:N-1; 32 | [I,J]=meshgrid(i,j); 33 | A=sqrt(2/N)*cos(((2.*I+1).*J*pi)/(N*2)); 34 | A(1,:)=A(1,:)./sqrt(2); 35 | A=A'; 36 | if D==1 37 | elseif D==2 38 | B=zeros(N,N,N,N); 39 | for i=1:N 40 | for j=1:N 41 | B(:,:,i,j)=A(:,i)*A(:,j)'; 42 | %max(max(B(:,:,i,j)))-min(min(B(:,:,i,j))) 43 | end; 44 | end; 45 | A=B; 46 | end; 47 | -------------------------------------------------------------------------------- /Dctlab/idct2sq.m: -------------------------------------------------------------------------------- 1 | function X=idct2sq(Y) 2 | %X = idct2sq(Y) 3 | %Version: 3.01, Date: 2008/03/02, author: Nikola Sprljan 4 | %2D IDCT optimised for square matrices 5 | % 6 | %Input: 7 | % Y - DCT coefficients matrix (must be square as no check is performed) 8 | % 9 | %Output: 10 | % X - just a matrix, what else? :) 11 | % 12 | %Note: 13 | % Take a look at the note for dct2sq.m! 14 | % 15 | %Example: 16 | % X = idct2sq(Y); 17 | 18 | n = size(Y,1); 19 | ww = sqrt(2*n) * exp(j*(0:n-1)*pi/(2*n)).'; 20 | ww(1) = ww(1)/sqrt(2); 21 | W = repmat(ww,[1 n]); 22 | 23 | X = idctsq1D(idctsq1D(Y,W,n)',W,n)'; 24 | 25 | function a = idctsq1D(bb,W,n) 26 | yy = W.*bb; 27 | y = real(ifft(yy)); 28 | %this below is to avoid n = 2^k strangeness 29 | a = zeros(n-1,n); 30 | a(1,:) = y(1,:); 31 | a(3:2:n,:) = y(2:n/2,:); 32 | a(2:2:n-2,:) = y(n:-1:n/2+2,:); 33 | a(n,:) = y(n/2+1,:); -------------------------------------------------------------------------------- /JSCCImage/AWGN1_RCPC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/JSCCImage/AWGN1_RCPC.png -------------------------------------------------------------------------------- /JSCCImage/BSC_BER.m: -------------------------------------------------------------------------------- 1 | function [OutputStream,parametar]=BSC_BER(InputStream,parametar) 2 | %[OutputStream,parametar]=BSC_BER(InputStream,parametar) 3 | %Simulation of the Binary Symemtric Channel (BSC) 4 | % 5 | %Input: 6 | % InputStream - input stream of bits (1 and -1) 7 | % parametar - bit error rate (ber) of the channel or a complete definition 8 | % of the channel, see in get_channel.m 9 | % 10 | %Output: 11 | % OutputStream - output stream of bits, after transmission through the 12 | % channel 13 | % parametar - the same as the input variable, here due to API compatibility 14 | % with other channels 15 | % 16 | %Uses: 17 | % randsrc (MATLAB Communication Toolbox) 18 | % 19 | %Example: 20 | % out=BSC_BER(randsrc(1,1024,[-1 1]),0.5); 21 | 22 | if isstruct(parametar) 23 | BER=parametar.BER; 24 | else 25 | BER=parametar; 26 | end; 27 | InputStream=InputStream<0; %converting from bipolar 28 | error_pattern=randsrc(1,length(InputStream),[0 1;BER 1-BER]); 29 | OutputStream=~xor(InputStream,error_pattern); 30 | OutputStream=-2*OutputStream+1; %back to bipolar -------------------------------------------------------------------------------- /JSCCImage/GE_awgn.m: -------------------------------------------------------------------------------- 1 | function [OutputStream,parametar]=GE_awgn(InputStream,parametar) 2 | %[OutputStream,parametar]=GE_awgn(InputStream,parametar) 3 | %Version: 1.00, Date: 2003, author: Nikola Sprljan 4 | %Simulation of the Gilbert-Elliot (GE) channel, using two AWGN channels 5 | % 6 | %Input: 7 | % InputStream - input stream of symbols (1 and -1) 8 | % parametar - a complete definition of the channel, see in get_channel.m 9 | % 10 | %Output: 11 | % OutputStream - output stream of symbols with added noise 12 | % parametar - a complete definition of the channel, with the current state 13 | % of the channel 14 | % 15 | %Note: 16 | % BPSK modulation is assumed, the power of the signal can be set with the 17 | % variable 'SignalPower'. 18 | % 19 | %Example: 20 | % [ch_handle,parametar]=get_channel('GE1'); 21 | % [OutputStream,parametar]=GE_awgn(randsrc(1,1024,[-1 1]),parametar) 22 | 23 | %CONSTANTS 24 | SignalPower=1; %power of the input signal in Watts 25 | % 26 | n=length(InputStream); 27 | SNR=zeros(1,n); 28 | if parametar.state==-1 29 | r=rand; 30 | parametar.state=r>(parametar.PGB/parametar.PBG); 31 | %parametar.numbad=r; 32 | end; 33 | % SNRg=2*(erfcinv(2*parametar.BERg)^2 * 10^(parametar.gain/10)); 34 | % SNRb=2*(erfcinv(2*parametar.BERb)^2 * 10^(parametar.gain/10)); 35 | SNRg=2*10^((20*log10(erfcinv(2*parametar.BERg)) + parametar.gain)/10); 36 | SNRb=2*10^((20*log10(erfcinv(2*parametar.BERb)) + parametar.gain)/10); 37 | for i=1:n 38 | r=rand; 39 | if parametar.state==0 40 | if r 0,1,'1' 8 | 9 | 8/9 10 | [Hag88] 11 | Memory=6 12 | CodeGenerator=[133 171 145] 13 | PunctCode=f78800 14 | cd=[0,0,24,740,13321,217761,3315491,48278177] 15 | %Punctcode=[f7,88,00]=[1 1 1 1 0 1 1 1,1 0 0 0 1 0 0 0,0 0 0 0 0 0 0 0] 16 | 17 | 4/5 = 8/10 18 | [Hag88] 19 | Memory=6 20 | CodeGenerator=[133 171 145] 21 | PunctCode=ff8800 22 | cd=[0,0,0,24,376,3464,30512,242734,1890790] 23 | %Punctcode=[ff,88,00]=[1 1 1 1 1 1 1 1,1 0 0 0 1 0 0 0,0 0 0 0 0 0 0 0] 24 | 25 | 2/3 = 8/12 26 | [Hag88] 27 | Memory=6 28 | CodeGenerator=[133 171 145] 29 | PunctCode=ffaa00 30 | cd=[0,0,0,0,0,12,280,1140,5104,24640,108512] 31 | %Punctcode=[ff,aa,00]=[1 1 1 1 1 1 1 1,1 0 1 0 1 0 1 0,0 0 0 0 0 0 0 0] 32 | 33 | 4/7 = 8/14 34 | [Hag88] 35 | Memory=6 36 | CodeGenerator=[133 171 145] 37 | PunctCode=ffee00 38 | cd=[0,0,0,0,0,0,12,74,386,1162,3542,11666] 39 | %Punctcode=[ff,ee,00]=[1 1 1 1 1 1 1 1,1 1 1 0 1 1 1 0,0 0 0 0 0 0 0 0] 40 | 41 | 1/2 = 8/16 42 | [Hag88] 43 | Memory=6 44 | CodeGenerator=[133 171 145] 45 | PunctCode=ffff00 46 | cd=[0,0,0,0,0,0,0,0,0,288,0,1688,0,11232] 47 | %Punctcode=[ff,ff,00]=[1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,0 0 0 0 0 0 0 0] 48 | 49 | 4/9 = 8/18 50 | [Hag88] 51 | Memory=6 52 | CodeGenerator=[133 171 145] 53 | PunctCode=ffff88 54 | cd=[0,0,0,0,0,0,0,0,0,14,82,182,320,810,1882] 55 | %Punctcode=[ff,ff,88]=[1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 0 0 0 1 0 0 0] 56 | 57 | 2/5 = 4/10 = 8/20 58 | [Hag88] 59 | Memory=6 60 | CodeGenerator=[133 171 145] 61 | PunctCode=ffffcc 62 | cd=[0,0,0,0,0,0,0,0,0,0,8,44,80,138,444,750] 63 | %Punctcode=[ff,ff,aa]=[1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 0 0 1 1 0 0] 64 | 65 | 4/11 = 8/22 66 | [Hag88] 67 | Memory=6 68 | CodeGenerator=[133 171 145] 69 | PunctCode=ffffee 70 | cd=[0,0,0,0,0,0,0,0,0,0,0,2,16,70,90,172,474] 71 | %Punctcode=[ff,ff,ee]=[1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 0 1 1 1 0] 72 | 73 | 1/3 = 8/24 74 | [Hag88] 75 | Memory=6 76 | CodeGenerator=[133 171 145] 77 | PunctCode=ffffff 78 | cd=[0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,160,0,424] 79 | %Punctcode=[ff,ff,ff]=[1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1] -------------------------------------------------------------------------------- /JSCCImage/RCPC_ch_epsilon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/JSCCImage/RCPC_ch_epsilon.png -------------------------------------------------------------------------------- /JSCCImage/RCPC_ch_ro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/JSCCImage/RCPC_ch_ro.png -------------------------------------------------------------------------------- /JSCCImage/RCPC_decode.m: -------------------------------------------------------------------------------- 1 | function OutputStream=RCPC_decode(InputStream,Memory,t,PunctInd,DepunctLen,PacketData) 2 | 3 | if Memory==0 4 | OutputStream=InputStream<0; %from bipolar to {0,1} 5 | return; 6 | end; 7 | InPunctStream=zeros(1,DepunctLen); 8 | retrans=ceil(length(PunctInd)/DepunctLen); 9 | if retrans>1 10 | repetition=zeros(1,DepunctLen); 11 | for i=1:retrans 12 | if i==retrans 13 | add_indices=(i-1)*DepunctLen+1:length(PunctInd); 14 | else 15 | add_indices=(i-1)*DepunctLen+1:i*DepunctLen; 16 | end; 17 | addSymbols=PunctInd(add_indices); 18 | repetition(addSymbols)=repetition(addSymbols)+1; 19 | InPunctStream(addSymbols)=InPunctStream(addSymbols)+InputStream(add_indices); 20 | end; 21 | InPunctStream=InPunctStream./repetition; 22 | else 23 | InPunctStream(PunctInd)=InputStream; 24 | end; 25 | % Rounding for BSC channel through unquant decision 26 | % InPunctStream(InPunctStream>0)=1; 27 | % InPunctStream(InPunctStream<0)=-1; 28 | % OutputStream=vitdec(InPunctStream,t,nOut,'term','unquant'); 29 | %Quantization for the soft decision 30 | nsdec=8; %8 31 | steppart=2^(1-nsdec); 32 | range=2^nsdec-1; 33 | InPunctStreamQ=range-floor((InPunctStream+1)./steppart); 34 | InPunctStreamQ(InPunctStreamQ<0)=0; 35 | InPunctStreamQ(InPunctStreamQ>range)=range; 36 | try 37 | OutputStream=vitdec(InPunctStreamQ,t,PacketData+Memory,'term','soft',nsdec); %soft decision 38 | catch 39 | pause; 40 | end; 41 | OutputStream=OutputStream(1:PacketData); -------------------------------------------------------------------------------- /JSCCImage/RCPC_encode.m: -------------------------------------------------------------------------------- 1 | function [OutputStreamPunct,OutputStream]=RCPC_encode(InputStream,Memory,t,P,PunctInd) 2 | 3 | if length(InputStream)>1 4 | if Memory==0 5 | OutputStream=InputStream; 6 | OutputStreamPunct=-2*OutputStream+1; 7 | return; 8 | end; 9 | InputStream=[InputStream zeros(1,Memory)]; % add zeros to terminate trellis 10 | n=length(InputStream); %length of extended input bitstream 11 | %Convolutional coding 12 | OutputStream=-2*convenc(InputStream,t,0)+1; % output bitstream without puncturing 13 | %Puncturing 14 | OutputStreamPunct=OutputStream(PunctInd); %add extra symbols and make signal bipolar (1->-1; 0->1) 15 | end; -------------------------------------------------------------------------------- /JSCCImage/RCPC_performance/RCPC_performance_10000x250.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/JSCCImage/RCPC_performance/RCPC_performance_10000x250.mat -------------------------------------------------------------------------------- /JSCCImage/RCPC_performance/RCPC_performance_AWGN1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/JSCCImage/RCPC_performance/RCPC_performance_AWGN1.mat -------------------------------------------------------------------------------- /JSCCImage/RCPC_performance/RCPC_performance_AWGN2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/JSCCImage/RCPC_performance/RCPC_performance_AWGN2.mat -------------------------------------------------------------------------------- /JSCCImage/RCPC_performance/RCPC_performance_BSC1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/JSCCImage/RCPC_performance/RCPC_performance_BSC1.mat -------------------------------------------------------------------------------- /JSCCImage/RCPC_performance/RCPC_performance_GE1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/JSCCImage/RCPC_performance/RCPC_performance_GE1.mat -------------------------------------------------------------------------------- /JSCCImage/RCPC_performance/info.txt: -------------------------------------------------------------------------------- 1 | Directory to store the RCPC codes performances for channels defined in [Toolbox]\channels 2 | The script to be used to generate the RCPC characteristics is script_channel_performance. -------------------------------------------------------------------------------- /JSCCImage/RCPC_test_equal_data.m: -------------------------------------------------------------------------------- 1 | function [diffvec,BER,PER]=RCPC_test_equal_data(hmany,data_siz,chnlname,PunctRate,CRC_siz,gain) 2 | %BitTot - upper limit of data bits sent 3 | %data_siz - size of data portion of packet 4 | %parametar - parametar for selected channel type 5 | %PunctRate - string that defines the used RCPC code (defined in text file 6 | % "punct_codes.txt" (i.e. '1/2', '4/7',...) 7 | %CRC_siz - size in bits of CRC check that is added to each packet 8 | 9 | DetectedErr=0; 10 | CRCDetErr=0; 11 | [ch_handle,parametar]=get_channel(chnlname); 12 | parametar.gain=gain; 13 | [Memory,Ib,Kb,t,PN,P,TotRate,PunctInd]=get_RCPC_code(PunctRate); 14 | fprintf('Mother code rate: 1/%d\n',PN/P); 15 | fprintf('Puncturing code rate: %d/%d\n',length(PunctInd),PN); 16 | fprintf('Total rate: %d/%d\n',Ib,Kb); 17 | packet_siz=Kb*(data_siz+CRC_siz+Memory)/Ib; 18 | if packet_siz~=round(packet_siz) 19 | packet_siz=round(packet_siz/Kb)*Kb; 20 | data_siz=(packet_siz/Kb)*Ib-Memory-CRC_siz; 21 | fprintf('FIRST POSSIBLE DATA SIZE: %d\n',data_siz); 22 | end; 23 | [PunctIndFull,PacketData,DepunctLen]=Punct_Variables(Memory,Ib,Kb,PN,P,PunctInd,packet_siz,CRC_siz); 24 | 25 | fprintf('Packet size: %d\n',packet_siz); 26 | fprintf('Number of packets: %d\n',hmany); 27 | fprintf('Transmitted data bits: %d\n',hmany*PacketData); 28 | 29 | errbit=zeros(1,hmany); 30 | diffvec=zeros(1,PacketData); 31 | for i=1:hmany 32 | %InPckt=InStream((i-1)*PacketData+1:i*PacketData); 33 | InPckt=randint(PacketData,1,2)'; 34 | if CRC_siz==0 35 | CRC=[]; 36 | else 37 | CRC=generic_crc(InPckt,CRC_siz); 38 | end; 39 | %Convolutional encoding + puncturing 40 | OutputStreamPunct=RCPC_encode([CRC InPckt],Memory,t,P,PunctIndFull); % OutputStreamPunct is bipolar!! %,packet_siz 41 | %AWGN channel - awgn_EsN0 function 42 | %BSC channel - BSC_BER function 43 | [OutputStreamPunctCh,parametar]=feval(ch_handle,OutputStreamPunct,parametar); %Power of the signal is now 1, i.e. 0dBW 44 | %Viterbi decoding 45 | CRCOutPckt=RCPC_decode(OutputStreamPunctCh,Memory,t,PunctIndFull,DepunctLen,PacketData+CRC_siz); 46 | %Error detection 47 | OutPckt=CRCOutPckt(CRC_siz+1:end); 48 | diffPckt=OutPckt~=InPckt; 49 | diffvec=diffvec+diffPckt; 50 | errbit(i)=sum(diffPckt); 51 | if CRC_siz>0 %check CRC 52 | CRC=CRCOutPckt(1:CRC_siz); 53 | CRCerr=any(generic_crc(OutPckt,CRC_siz)~=CRC); 54 | DetectedErr=DetectedErr+CRCerr; 55 | if errbit(i) & CRCerr 56 | CRCDetErr=CRCDetErr+1; 57 | end; 58 | end; 59 | end; 60 | %inderr=find(OutputStream~=InStream); 61 | TotErrors=sum(errbit); 62 | BER=TotErrors/(hmany*PacketData); 63 | TotPcktErrors=sum(errbit>0); 64 | PER=TotPcktErrors/hmany; 65 | fprintf('\n***Errors Statistics***\n'); 66 | fprintf('Errors = %d\nBER = %f\n',TotErrors,BER); 67 | fprintf('Packet errors = %d\nPER = %f\n',TotPcktErrors,PER); 68 | fprintf('(CRC) Correctly detected packet errors = %d\n', CRCDetErr); 69 | fprintf('(CRC) Detected packet errors = %d\n\n', DetectedErr); -------------------------------------------------------------------------------- /JSCCImage/RCPC_test_equal_packet.m: -------------------------------------------------------------------------------- 1 | function [BER,PER]=RCPC_test_equal_packet(hmany,packet_siz,chnlname,PunctRate,CRC_siz,gain);%Memory,CodeGenerator,PunctCode,CRC_siz) 2 | %BitTot - upper limit of data bits sent 3 | %packet_siz - packet size (strictly given) 4 | %parametar - parametar for selected channel type 5 | %PunctRate - string that defines the used RCPC code (defined in text file 6 | % "punct_codes.txt" (i.e. '1/2', '4/7',...) 7 | %CRC_siz - size in bits of CRC check that is added to each packet 8 | % 9 | %if 8/N RCPC codes (P=8) and byte size compatible CRC are used then PacketData is 10 | %also byte size compatible, so no truncation or extension is necessary 11 | % -> this is especially convenient if RS column code is to be used 12 | 13 | DetectedErr=0; 14 | CRCDetErr=0; 15 | [ch_handle,parametar]=get_channel(chnlname); 16 | parametar.gain=gain; 17 | [Memory,Ib,Kb,t,PN,P,TotRate,PunctInd]=get_RCPC_code(PunctRate); 18 | fprintf('Mother code rate: 1/%d\n',PN/P); 19 | fprintf('Puncturing code rate: %d/%d\n',length(PunctInd),PN); 20 | fprintf('Total rate: %d/%d\n',Ib,Kb); 21 | [PunctIndFull,PacketData,DepunctLen]=Punct_Variables(Memory,Ib,Kb,PN,P,PunctInd,packet_siz,CRC_siz); 22 | 23 | fprintf('Data bits in packet: %d\n',PacketData); 24 | fprintf('Number of packets: %d\n',hmany); 25 | fprintf('Transmitted data bits: %d\n',hmany*PacketData); 26 | 27 | errbit=zeros(1,hmany); 28 | diffvec=zeros(1,PacketData); 29 | for i=1:hmany 30 | %InPckt=InStream((i-1)*PacketData+1:i*PacketData); 31 | InPckt=randint(PacketData,1,2)'; 32 | if CRC_siz==0 33 | CRC=[]; 34 | else 35 | CRC=generic_crc(InPckt,CRC_siz); 36 | %CRC=zeros(1,CRC_siz); 37 | end; 38 | %Convolutional encoding + puncturing 39 | OutputStreamPunct=RCPC_encode([CRC InPckt],Memory,t,P,PunctIndFull); % OutputStreamPunct is bipolar!! 40 | %AWGN channel - awgn_EsN0 function 41 | %BSC channel - BSC_BER function 42 | [OutputStreamPunctCh,parametar]=feval(ch_handle,OutputStreamPunct,parametar); %Power of the signal is now 1, i.e. 0dBW 43 | %Viterbi decoding 44 | CRCOutPckt=RCPC_decode(OutputStreamPunctCh,Memory,t,PunctIndFull,DepunctLen,PacketData+CRC_siz); 45 | %Error detection 46 | OutPckt=CRCOutPckt(CRC_siz+1:end); 47 | diffPckt=OutPckt~=InPckt; 48 | %diffvec=diffvec+diffPckt; 49 | errbit(i)=sum(diffPckt); 50 | if CRC_siz>0 %check CRC 51 | CRC=CRCOutPckt(1:CRC_siz); 52 | CRCerr=any(generic_crc(OutPckt,CRC_siz)~=CRC); 53 | DetectedErr=DetectedErr+CRCerr; 54 | if errbit(i) & CRCerr 55 | CRCDetErr=CRCDetErr+1; 56 | end; 57 | end; 58 | end; 59 | %inderr=find(OutputStream~=InStream); 60 | TotErrors=sum(errbit); 61 | BER=TotErrors/(hmany*PacketData); 62 | if CRC_siz>0 63 | TotPcktErrors=DetectedErr; 64 | else 65 | TotPcktErrors=sum(errbit>0); 66 | end; 67 | PER=TotPcktErrors/hmany; 68 | fprintf('\n***Errors Statistics***\n'); 69 | fprintf('Errors = %d\nBER = %f\n',TotErrors,BER); 70 | fprintf('Packet errors = %d\nPER = %f\n',TotPcktErrors,PER); 71 | fprintf('(CRC) Correctly detected packet errors = %d\n', CRCDetErr); 72 | fprintf('(CRC) Detected packet errors = %d\n\n', DetectedErr); -------------------------------------------------------------------------------- /JSCCImage/RD_curve/Lena256RD.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/JSCCImage/RD_curve/Lena256RD.mat -------------------------------------------------------------------------------- /JSCCImage/RD_curve/info.txt: -------------------------------------------------------------------------------- 1 | Directory to store the Rate-Distortion curves produced with RDcurveBytePrec.m -------------------------------------------------------------------------------- /JSCCImage/RDcurveBytePrec.m: -------------------------------------------------------------------------------- 1 | function [PSNR_RD8,MSE_RD8]=RDcurveBytePrec(imagename,totalmaxbits) 2 | header_size=51; 3 | wavelet='CDF_9x7'; 4 | no_decomp=7; 5 | start_size=8; 6 | end_size=ceil(totalmaxbits/8)*8; 7 | iminfo=imfinfo(imagename); 8 | imsize=prod(iminfo.Width*iminfo.Height); 9 | bpps=(start_size:8:end_size)'/imsize; 10 | [Arec,bitstream,PSNR_RD8,MSE_RD8]=spiht_wpackets(imagename,bpps,wavelet,no_decomp); 11 | [pathstr,filename] = fileparts(imagename); 12 | save(['.\RD_curve\' filename 'RD'],'PSNR_RD8','MSE_RD8'); -------------------------------------------------------------------------------- /JSCCImage/README.md: -------------------------------------------------------------------------------- 1 | Joint Source-Channel Coding of Images Toolbox 2 | ============================================= 3 | 4 | Simulation of transmission of SPIHT encoded images over unreliable channels. Requires the MATLAB Communications Toolbox. Scripts for measuring the channel error rate, RCPC code characteristics and Rate-Distortion (R-D) curve of the SPIHT compression for the input image and selected channel characteristics. 5 | 6 | Functions 7 | --------- 8 | 9 | - **awgn_EsN0** - Simulation of the Additive White Gaussian Noise (AWGN) channel 10 | - **BSC_BER** - Simulation of the Binary Symemtric Channel (BSC) 11 | - **GE_awgn** - Simulation of the Gilbert-Elliot (GE) channel, using two AWGN channels 12 | - **get_channel** - Loads a predefined channel (saved in a txt file) 13 | - **get\_RCPC\_code** - Loads a predefined RCPC code from a default code family ('Punct_codes.txt') 14 | - **RCPC_encode** - Rate Compatible Punctured Convolutional (RCPC) coding of the binary stream 15 | - **RCPC\_test\_equal_data** - Transmission of packets with constant data part, using RCPC 16 | - **RCPC\_test\_equal_packet** - Transmission of packets with constant size, using RCPC 17 | - **optimal\_RCPC_equal** - Computes the Equal Error Protection (EEP) scheme for a given image and channel 18 | - **send\_image_equal** - Transmission of SPIHT encoded image using EEP 19 | - **send\_image\_equal_RS** - Transmission of SPIHT encoded image using EEP and Reed-Solomon protection 20 | - **optimal\_RCPC_unequal** - Computes the Unequal Error Protection (UEP) scheme for a given image and channel 21 | - **send\_image_unequal** - Transmission of SPIHT encoded image using UEP 22 | - **script\_channel_performance** - Measures the BER and PER values for RCPC transmission on a given channel 23 | - **RDcurveBytePrec** - Runs SPIHT over range of target bitrates and stores the R-D curve 24 | 25 | Examples 26 | -------- 27 | **get_channel** (contents of the file `AWGN1.txt`): 28 | 29 | ch_handle=@awgn_EsN0; 30 | parametar.EsN0=-0.8556; 31 | parametar.state=-1; 32 | parametar.Bch=128000; 33 | parametar.Nch=256; 34 | 35 | 36 | **get\_RCPC_code** (one RCPC entry from the file `Punct_codes.txt`): 37 | 38 | 8/9 39 | [Hag88] 40 | Memory=6 41 | CodeGenerator=[133 171 145] 42 | PunctCode=f78800 43 | cd=[0,0,24,740,13321,217761,3315491,48278177] 44 | %Punctcode=[f7,88,00]=[1 1 1 1 0 1 1 1,1 0 0 0 1 0 0 0,0 0 0 0 0 0 0 0] 45 | 46 | 47 | **RCPC_encode**: 48 | 49 | >> signal=round(rand(1,8)) 50 | signal = 51 | 0 1 1 0 0 0 1 0 52 | >> [Memory,Ib,Kb,t,PN,P,TotRate,PunctInd] = get_RCPC_code('8/9'); 53 | >> outsignal = RCPC_encode(signal,Memory,t,P,PunctInd) 54 | outsignal = 55 | 1 1 -1 -1 -1 1 -1 1 1 56 | 57 | **RCPC\_test\_equal_data**: 58 | 59 | >> [diffvec,BER,PER]=RCPC_test_equal_data(100,128,'AWGN1','1/2',8,0); 60 | Mother code rate: 1/3 61 | Puncturing code rate: 16/24 62 | Total rate: 1/2 63 | Packet size: 284 64 | Number of packets: 100 65 | Transmitted data bits: 12800 66 | 67 | ***Errors Statistics*** 68 | Errors = 52 69 | BER = 0.004063 70 | Packet errors = 12 71 | PER = 0.120000 72 | (CRC) Correctly detected packet errors = 12 73 | (CRC) Detected packet errors = 12 74 | 75 | **script\_channel_performance**: 76 | 77 | >> script_channel_performance(@RCPC_test_equal_packet,100000,16,'GE1'); 78 | 79 | ![RCPC codes epsilon characteristic](https://github.com/nsprljan/ImageCodingResearchTools/raw/master/JSCCImage/RCPC_ch_epsilon.png) 80 | 81 | ![RCPC codes ro characteristic](https://github.com/nsprljan/ImageCodingResearchTools/raw/master/JSCCImage/RCPC_ch_ro.png) 82 | 83 | **optimal\_RCPC_equal**: 84 | 85 | >> optimal_RCPC_equal(1000,16,'GE1','Lena512RD','draw_small'); 86 | RCPC total rate: 1/1 - average PSNR: 17.281731 87 | RCPC total rate: 8/9 - average PSNR: 18.406105 88 | RCPC total rate: 4/5 - average PSNR: 18.432578 89 | RCPC total rate: 2/3 - average PSNR: 19.129653 90 | RCPC total rate: 4/7 - average PSNR: 21.051831 91 | RCPC total rate: 1/2 - average PSNR: 24.052347 92 | RCPC total rate: 4/9 - average PSNR: 26.976499 93 | RCPC total rate: 2/5 - average PSNR: 29.522427 94 | RCPC total rate: 4/11 - average PSNR: 30.491567 95 | RCPC total rate: 1/3 - average PSNR: 30.432119 96 | *** 97 | Minimal distortion RCPC code: 4/11 98 | PSNR: 30.491567 99 | 100 | ![RCPC plots for AWGN1 and EEP](https://github.com/nsprljan/ImageCodingResearchTools/raw/master/JSCCImage/AWGN1_RCPC.png) 101 | 102 | -------------------------------------------------------------------------------- /JSCCImage/awgn_EsN0.m: -------------------------------------------------------------------------------- 1 | function [OutputStream,parametar]=awgn_EsN0(InputStream,parametar) 2 | %[OutputStream,parametar]=awgn_EsN0(InputStream,parametar) 3 | %Simulation of the Additive White Gaussian Noise (AWGN) channel 4 | % 5 | %Input: 6 | % InputStream - input stream of symbols (1 and -1) 7 | % parametar - signal to noise ratio (Es/N0) of the channel or a complete 8 | % definition of the channel, see in get_channel.m 9 | % 10 | %Output: 11 | % OutputStream - output stream of symbols with added noise 12 | % parametar - the same as the input variable, here due to API compatibility 13 | % with other channels 14 | % 15 | %Note: 16 | % BPSK modulation is assumed, the power of the signal can be set with the 17 | % variable 'SignalPower'. 18 | % 19 | %Example: 20 | % out=awgn_EsN0(randsrc(1,1024,[-1 1]),10); 21 | 22 | %CONSTANTS 23 | SignalPower=1; %power of the input signal in Watts 24 | % 25 | if isstruct(parametar) 26 | SNR=10*log10(2)+parametar.EsN0+parametar.gain; %SNR is Es/sigma^2 = 0.5*(Es/N0) 27 | else 28 | SNR=10*log10(2)+parametar; 29 | end; 30 | NoisePower=SignalPower*10^(-SNR/10); 31 | %randn generates normally distributed random numbers with sigma=1 (Power=1) 32 | Noise=sqrt(NoisePower)*randn(1,length(InputStream)); 33 | OutputStream=InputStream+Noise; -------------------------------------------------------------------------------- /JSCCImage/channels/AWGN1.txt: -------------------------------------------------------------------------------- 1 | ch_handle=@awgn_EsN0; 2 | parametar.EsN0=-0.8556; 3 | parametar.state=-1; 4 | parametar.Bch=128000; 5 | parametar.Nch=256; 6 | parametar.gain=0; -------------------------------------------------------------------------------- /JSCCImage/channels/AWGN2.txt: -------------------------------------------------------------------------------- 1 | ch_handle=@awgn_EsN0; 2 | parametar.EsN0=4.3232; 3 | parametar.state=-1; 4 | parametar.Bch=128000; 5 | parametar.Nch=256; 6 | parametar.gain=0; -------------------------------------------------------------------------------- /JSCCImage/channels/AWGN_0dB.txt: -------------------------------------------------------------------------------- 1 | ch_handle=@awgn_EsN0; 2 | parametar.EsN0=0; 3 | parametar.state=-1; 4 | parametar.Bch=128000; 5 | parametar.Nch=256; 6 | parametar.gain=0; -------------------------------------------------------------------------------- /JSCCImage/channels/BSC1.txt: -------------------------------------------------------------------------------- 1 | ch_handle=@BSC_BER; 2 | parametar.BER=1e-2; 3 | parametar.state=-1; 4 | parametar.Bch=128000; 5 | parametar.Nch=256; 6 | parametar.gain=0; -------------------------------------------------------------------------------- /JSCCImage/channels/GE1.txt: -------------------------------------------------------------------------------- 1 | ch_handle=@GE_awgn; 2 | parametar.EsN0=0; 3 | parametar.PGB=1/3600; 4 | parametar.PBG=1/400; 5 | parametar.BERg=0.0005; 6 | parametar.BERb=0.1; 7 | parametar.state=-1; 8 | parametar.Bch=128000; 9 | parametar.Nch=256; 10 | parametar.gain=0; -------------------------------------------------------------------------------- /JSCCImage/compute_gain.m: -------------------------------------------------------------------------------- 1 | function g=compute_gain(imgname,PSNRinp,chnlname,gain) 2 | 3 | [ch_handle,parametar]=get_channel(chnlname); 4 | EsN0inp=parametar.EsN0+gain; 5 | [pathstr,filename]=fileparts(imgname); 6 | %..uncodedPSNR_....mat file contains variable PSNRmean 7 | 8 | if findstr('AWGN',chnlname) 9 | load([filename 'uncodedPSNR_AWGN'],'PSNRmean'); 10 | else 11 | load([filename 'uncodedPSNR_' chnlname],'PSNRmean'); 12 | end; 13 | PSNR=PSNRmean(1,:); 14 | EN=PSNRmean(2,:); 15 | if PSNRinp==PSNR(1) %no gain is achieved 16 | g=0; 17 | else 18 | Ind=find(PSNR>PSNRinp); 19 | PSNRup=PSNR(Ind(1)); 20 | ENup=EN(Ind(1)); 21 | PSNRdn=PSNR(Ind(1)-1); 22 | ENdn=EN(Ind(1)-1); 23 | EsN0unc=ENdn+(ENup-ENdn)*(PSNRinp-PSNRdn)/(PSNRup-PSNRdn); 24 | g=EsN0unc-EsN0inp; 25 | end; -------------------------------------------------------------------------------- /JSCCImage/generic_crc.m: -------------------------------------------------------------------------------- 1 | function crc=generic_crc(input,gen_poly) 2 | %accepts binary inputs and computes CRC 3 | %if gen_poly is just one number in length the it doesn't 4 | %represent generator polynomial but the length of the CRC 5 | %which will be searched in the tables 6 | %example of gen_poly -> [1 1 0 1]=1+x+x^3 7 | 8 | gpl=length(gen_poly); 9 | if gpl==1 10 | switch gen_poly 11 | case 0 12 | crc=[];return 13 | case 4 14 | gpl=5; 15 | gen_poly=[1 1 1 1 1]; % 1 + x^1 + x^2 + x^3 + x^4 16 | case 8 17 | gpl=9; 18 | gen_poly=[1 0 1 0 1 0 1 1 1]; % 1 + x^2 + x^4 + x^6 + x^7 + x^8 19 | case 10 20 | gpl=11; 21 | %gen_poly=[1 0 1 0 1 0 1 0 1 0 1]; % 1 + x^2 + x^4 + x^6 + x^8 + x^10 22 | gen_poly=[1 1 0 0 1 1 0 0 0 1 1]; % 1 + x + x^4 + x^5 + x^9 + x^10 23 | case 16 24 | gpl=17; 25 | %gen_poly=[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1]; % 1 + x + x^15 + x^16 26 | gen_poly=[1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1]; % 1 + x^2 + x^15 + x^16 27 | end; 28 | end; 29 | crc=zeros(1,gpl-1); 30 | [q,rem] = gfdeconv([zeros(1,gpl-1) input],gen_poly); 31 | crc(1:length(rem))=rem; -------------------------------------------------------------------------------- /JSCCImage/get_RCPC_code.m: -------------------------------------------------------------------------------- 1 | function [Memory,Ib,Kb,t,PN,P,TotRate,PunctInd]=get_RCPC_code(PunctRate) 2 | %[Memory,Ib,Kb,t,PN,P,TotRate,PunctInd]=get_RCPC_code(PunctRate) 3 | %Version: 1.00, Date: 2003, author: Nikola Sprljan 4 | %Loads a predefined RCPC code from a default code family ('Punct_codes.txt') 5 | % 6 | %Input: 7 | % PunctRate - string specifyng the code rate, e.g. '1/2' or '13' 8 | % 9 | %Output: 10 | % Memory - length of the shifting registers 11 | % Ib - numerator of the code rate 12 | % Kb - denominator of the code rate 13 | % t - trellis to be used 14 | % PN - puncturing period of the output stream 15 | % P - puncturing period of the input stream 16 | % TotRate - code rate 17 | % PunctInd - indices of the output symbols NOT to be removed in one 18 | % puncturing period 19 | %Example: 20 | % [Memory,Ib,Kb,t,PN,P,TotRate,PunctInd]=get_RCPC_code('1/3'); 21 | 22 | %[s,f,tokens] = regexp(PunctRate,'(\w*)/(\w*)'); 23 | %Ib=str2num(PunctRate(tokens{1}(1,1):tokens{1}(1,2))); 24 | %Kb=str2num(PunctRate(tokens{1}(2,1):tokens{1}(2,2))); 25 | slashind=findstr(PunctRate,'/'); 26 | Ib=str2num(PunctRate(1:slashind-1)); 27 | Kb=str2num(PunctRate(slashind+1:end)); 28 | 29 | fid=fopen('Punct_codes.txt','r'); 30 | flag=0; 31 | %expression=['^\<' PunctRate]; 32 | while 1 33 | tline = fgetl(fid); 34 | if ~ischar(tline) break; end; 35 | switch flag 36 | case 0 37 | if findstr(tline,PunctRate) %regexp(tline,expression) 38 | flag=1; 39 | end; 40 | case 1 41 | flag=2; 42 | case 2 43 | Memory=str2num(tline(8:end)); 44 | flag=3; 45 | case 3 46 | CodeGenerator=str2num(tline(15:end)); 47 | flag=4; 48 | case 4 49 | PunctCode=tline(11:end); 50 | flag=5; 51 | case 5 52 | cd=str2num(tline(4:end)); 53 | break; 54 | end; 55 | end; 56 | fclose(fid); 57 | 58 | N=length(CodeGenerator); %N of 1/N "mother" code 59 | PunctBin=dec2bin(hex2dec(PunctCode)); 60 | P=length(PunctBin)/N; %InputStream period of puncturing 61 | PN=P*N; %OutputStream period of puncturing 62 | PunctSiz=sum(PunctBin=='1'); %number of bits in one period that gets transmitted after puncturing 63 | TotRate=Ib/Kb; 64 | t=poly2trellis(Memory+1,CodeGenerator); %create trellis structure 65 | PunctCodeRs=reshape(reshape(str2num(PunctBin')',[P N])',[1 PN]); 66 | PunctInd=find(PunctCodeRs); 67 | % RCPC_err_fhandle=@RCPC_err; 68 | % 69 | % function Pb=RCPC_err(cd,P,EsN0) 70 | % EsN0=10^(EsN0/10); 71 | % Pb=0; 72 | % d=1:length(cd); 73 | % Pb=sum(cd(d).*0.5.*erfc(sqrt(d.*EsN0)))/P; -------------------------------------------------------------------------------- /JSCCImage/get_channel.m: -------------------------------------------------------------------------------- 1 | function [ch_handle,parametar]=get_channel(chnlname) 2 | %[ch_handle,parametar]=get_channel(chnlname) 3 | %Version: 1.00, Date: 2003, author: Nikola Sprljan 4 | %Loads a predefined channel (saved in a txt file) 5 | % 6 | %Input: 7 | % chnlname - the file name of the channel definition, without the mandatory 8 | % extension '.txt' 9 | % 10 | %Output: 11 | % ch_handle - function handle that simulates the channel 12 | % parametar - a complete definition of the channel, for an example see in 13 | % the channel definitions provided. 14 | % 15 | %Note: 16 | % The predefined location of the channels is the directory '\channels'. 17 | % The common part of all channel descriptions is the function handler that 18 | % simulates it, and the following parameters: 19 | % state - state(?) of the channel 20 | % Bch - bandwidth of the channel in bps 21 | % Nch - packet size in bits defined on the channel 22 | % gain - defintion of power gain (attenuation) of the channel. 23 | %Specific parameters, for the provided channels include: 24 | % BSC channel: 25 | % BER - bit error rate 26 | % AWGN channel: 27 | % EsN0 - signal to noise ratio (Es/N0) 28 | % GE channel: 29 | % EsN0 - signal to noise ratio (Es/N0) 30 | % PGB - probability of switching from good to bad state of the channel 31 | % PBG - probability of switching from bad to good state of the channel 32 | % BERg - BER when the channel is in its good state 33 | % BERb - BER when the channel is in its bad state 34 | % 35 | %Example: 36 | % [ch_handle,parametar]=get_channel('GE1'); 37 | 38 | fid=fopen(['.\channels\' chnlname '.txt'],'r'); 39 | while 1 40 | tline = fgetl(fid); 41 | if ~ischar(tline) break; end; 42 | eval(tline); 43 | end; 44 | fclose(fid); -------------------------------------------------------------------------------- /JSCCImage/optimal_RCPC_equal.m: -------------------------------------------------------------------------------- 1 | function [equal_RCPC,minD_equal]=optimal_RCPC_equal(trans_time,CRC_siz,chnlname,RDfile,draw) 2 | % 3 | %the variable MSE_RD8 contains the Rate-Distortion curve of an image 4 | %encoded with SPIHT, measured at byte points. On the other hand, num_bits 5 | %specifies the number of bits, so for each consecutive 8 bits the RD value 6 | %of an image will be the same. The difference in performance due to this 7 | %lack of precision should be negligible. 8 | 9 | prob_res=1000; 10 | RCPC{1}='1/1';ls{1}='--';lw{1}=1;lb{1}='k'; 11 | RCPC{2}='8/9';ls{2}='-';lw{2}=1;lb{2}='k'; 12 | RCPC{3}='4/5';ls{3}='-.';lw{3}=2;lb{3}=[0.753 0.753 0.753]; 13 | RCPC{4}='2/3';ls{4}=':';lw{4}=2;lb{4}=[0.753 0.753 0.753]; 14 | RCPC{5}='4/7';ls{5}='--';lw{5}=2;lb{5}=[0.753 0.753 0.753]; 15 | RCPC{6}='1/2';ls{6}='-';lw{6}=2;lb{6}=[0.753 0.753 0.753]; 16 | RCPC{7}='4/9';ls{7}='-.';lw{7}=2;lb{7}='k'; 17 | RCPC{8}='2/5';ls{8}=':';lw{8}=2;lb{8}='k'; 18 | RCPC{9}='4/11';ls{9}='--';lw{9}=2;lb{9}='k'; 19 | RCPC{10}='1/3';ls{10}='-';lw{10}=2;lb{10}='k'; 20 | if findstr(draw,'draw') 21 | %figure for results 22 | set(0,'Units','pixels'); 23 | scnsize = get(0,'ScreenSize'); 24 | ticks=0.1:0.1:1; 25 | xdat=1/prob_res:1/prob_res:1; 26 | fig=figure; 27 | for i=1:10 ticksc{i}=[num2str(round(ticks(i)*100)) '%'];end; 28 | if strcmp(draw,'draw_small') 29 | ah=axes('XLim',[0 1],'Box','on','FontSize',10,'XGrid','on','XTick',ticks,'XTickLabel',ticksc); 30 | ylabel('{\itPSNR} [dB]','FontName','Times New Roman','FontSize',16); 31 | xlabel('\Phi','FontName','Times New Roman','FontSize',16); 32 | else 33 | ah=axes('XLim',[0 1],'Box','on','FontSize',14,'XGrid','on','XTick',ticks,'XTickLabel',ticksc); 34 | ylabel('{\itPSNR} [dB]','FontName','Times New Roman','FontSize',24); 35 | xlabel('\Phi','FontName','Times New Roman','FontSize',24); 36 | end; 37 | end; 38 | minPSNR=Inf;maxPSNR=0; 39 | %get channel parameters 40 | [ch_handle,parametar]=get_channel(chnlname); 41 | packet_siz=parametar.Nch; 42 | channel_bits=(parametar.Bch*trans_time)/1000; 43 | num_packets=floor(channel_bits/packet_siz); %number of packets that satisfy the time condition 44 | %load BER and PER charateristics 45 | load(['.\RCPC_performance\RCPC_performance_' chnlname],'BER','PER'); 46 | %load the pre-computed byte-precision R-D curve 47 | load(['.\RD_curve\' RDfile],'PSNR_RD8','MSE_RD8'); 48 | 49 | min_MSE=Inf; 50 | prob_arrival=zeros(1,num_packets+1); 51 | MSE=zeros(1,num_packets+1); 52 | for i=1:10 53 | [Memory,Ib,Kb,t,PN,P,TotRate,PunctInd]=get_RCPC_code(RCPC{i}); 54 | [PunctIndFull,PacketData(i),DepunctLen]=Punct_Variables(Memory,Ib,Kb,PN,P,PunctInd,packet_siz,CRC_siz); 55 | total_bits=num_packets*PacketData(i); 56 | avg_bits=0; 57 | avg_MSE_cur=0; 58 | pckt_error=PER(i); 59 | pckt_correct=1-PER(i); 60 | %prob_arrival=zeros(1,num_packets); 61 | for j=0:num_packets 62 | num_bits=j*PacketData(i); 63 | if j==num_packets 64 | prob_arrival(j+1)=(pckt_correct^j); 65 | %avg_bits=avg_bits+prob_arrival*num_bits; 66 | else 67 | prob_arrival(j+1)=(pckt_correct^j)*pckt_error; 68 | %avg_bits=avg_bits+prob_arrival*num_bits; 69 | end; 70 | if num_bits==0 71 | MSE(j+1)=MSE_RD8(1); 72 | else 73 | %MSE=MSE_RD8(floor(num_bits/8)); 74 | MSE(j+1)=MSE_RD8(floor(num_bits/8)); 75 | end; 76 | avg_MSE_cur=avg_MSE_cur+prob_arrival(j+1)*MSE(j+1); 77 | end; 78 | avg_MSE(i)=avg_MSE_cur; 79 | %phi_PSNR to figure 80 | phi_PSNR=probMSE2phi(prob_res,prob_arrival,MSE); 81 | minPSNR=min([minPSNR phi_PSNR]); 82 | maxPSNR=max([maxPSNR phi_PSNR]); 83 | if findstr(draw,'draw') 84 | line('Parent',gca,'XData',xdat,'YData',phi_PSNR,'Tag',RCPC{i},'LineStyle',ls{i},'LineWidth',lw{i},'Color',lb{i}); 85 | %results to command prompt 86 | fprintf('RCPC total rate: %d/%d - ',Ib,Kb); 87 | %fprintf('Average number of bits received correctly: %f\n',avg_bits); 88 | %fprintf('Average MSE: %f\n',avg_MSE(i)); 89 | fprintf('average PSNR: %f\n',10*log10(255^2/avg_MSE(i))); 90 | end; 91 | if avg_MSE(i)0)))); 42 | figure('Position',[1 scnsize(4)/4 scnsize(3) 2*scnsize(4)/5]); 43 | berh=axes('Box','on','FontSize',14,'Position',[0.13 0.20 0.80 0.75],... 44 | 'XLim',[1 10],'XGrid','on','XTick',1:10,'XTickLabel',RCPC,... 45 | 'YScale','log','YLim',[10^lb 0.5],'YGrid','on','YTick',ticks(end+lb:end)); 46 | y=ylabel('{\it\epsilon}','FontName','Times New Roman','FontSize',24,'Rotation',0); 47 | x=xlabel('RCPC code','FontName','Times New Roman','FontSize',24); 48 | line('Parent',berh,'XData',1:10,'YData',BER,'LineStyle','-','LineWidth',2,'Color','k','Marker','o','MarkerSize',8); 49 | %enable for small plot 50 | set(berh,'FontSize',10); 51 | set(x,'FontSize',16); 52 | set(y,'FontSize',16); 53 | set(gcf,'Position',[100 100 352 240]); 54 | 55 | %PER 56 | lp=floor(log10(min(PER(PER>0)))); 57 | figure('Position',[1 scnsize(4)/4 scnsize(3) 2*scnsize(4)/5]); 58 | perh=axes('Box','on','FontSize',14,'Position',[0.13 0.20 0.80 0.75],... 59 | 'XLim',[1 10],'XGrid','on','XTick',1:10,'XTickLabel',RCPC,... 60 | 'YScale','log','YLim',[10^lp 1],'YGrid','on','YTick',ticks(end+lp:end)); 61 | y=ylabel('{\it\rho}','FontName','Times New Roman','FontSize',24,'Rotation',0); 62 | x=xlabel('RCPC code','FontName','Times New Roman','FontSize',24); 63 | line('Parent',perh,'XData',1:10,'YData',PER,'LineStyle','-','LineWidth',2,'Color','k','Marker','o','MarkerSize',8); 64 | %enable for small plot 65 | set(perh,'FontSize',10); 66 | set(x,'FontSize',16); 67 | set(y,'FontSize',16); 68 | set(gcf,'Position',[100 100 352 240]); -------------------------------------------------------------------------------- /JSCCImage/script_send_image_RCPC.m: -------------------------------------------------------------------------------- 1 | function script_send_image_RCPC(imgname,trans_time,chnlname,dir,method_hndl,hmany,RCPCind,varargin) 2 | %Equal protection - method_hndl=@send_image_equal 3 | RCPC{1}='1/1';ls{1}='--';lw{1}=1;lb{1}='k'; 4 | RCPC{2}='8/9';ls{2}='-';lw{2}=1;lb{2}='k'; 5 | RCPC{3}='4/5';ls{3}='-.';lw{3}=2;lb{3}=[0.753 0.753 0.753]; 6 | RCPC{4}='2/3';ls{4}=':';lw{4}=2;lb{4}=[0.753 0.753 0.753]; 7 | RCPC{5}='4/7';ls{5}='--';lw{5}=2;lb{5}=[0.753 0.753 0.753]; 8 | RCPC{6}='1/2';ls{6}='-';lw{6}=2;lb{6}=[0.753 0.753 0.753]; 9 | RCPC{7}='4/9';ls{7}='-.';lw{7}=2;lb{7}='k'; 10 | RCPC{8}='2/5';ls{8}=':';lw{8}=2;lb{8}='k'; 11 | RCPC{9}='4/11';ls{9}='--';lw{9}=2;lb{9}='k'; 12 | RCPC{10}='1/3';ls{10}='-';lw{10}=2;lb{10}='k'; 13 | gain=0; 14 | gains=zeros(1,10); 15 | status=mkdir(dir); 16 | % for j=1:length(RCPCind) 17 | % i=RCPCind(j); 18 | % %load([dir '\' chnlname 'RCPC' num2str(i)],'PSNR','PSNRmean','PSNRcum','Phi09','PhiPSNRmax','PSNRmax'); 19 | % [PSNR,PSNRmean,PSNRcum,Phi09,PhiPSNRmax,PSNRmax]=feval(method_hndl,imgname,trans_time,chnlname,RCPC{i},hmany,gain,varargin{:}); 20 | % %PhiPSNRmax=sum(PSNRcum==PSNRmax)/1000; 21 | % save([dir '\' chnlname 'RCPC' num2str(i)],'PSNR','PSNRmean','PSNRcum','Phi09','PhiPSNRmax','PSNRmax'); 22 | % end; 23 | set(0,'Units','pixels'); 24 | scnsize = get(0,'ScreenSize'); 25 | ticks=0.1:0.1:1; 26 | xdat=1/hmany:1/hmany:1; 27 | figure; 28 | for i=1:10 ticksc{i}=[num2str(round(ticks(i)*100)) '%'];end; 29 | ah=axes('XLim',[0 1],'Box','on','FontSize',14,'XGrid','on','XTick',ticks,'XTickLabel',ticksc); 30 | ylabel('{\itPSNR} [dB]','FontName','Times New Roman','FontSize',24); 31 | xlabel('\Phi','FontName','Times New Roman','FontSize',24); 32 | minPSNR=Inf;maxPSNR=0; 33 | for i=1:10 34 | load([dir '\' chnlname 'RCPC' num2str(i)],'PSNR','PSNRmean','PSNRcum','Phi09','PhiPSNRmax','PSNRmax'); 35 | minPSNR=min(minPSNR,PSNRcum(end)); 36 | maxPSNR=max(maxPSNR,PSNRcum(1)); 37 | if isempty(findstr('BSC',chnlname)) 38 | gains(i)=compute_gain(imgname,PSNRmean,chnlname,gain); 39 | end; 40 | fprintf('\n Rate %s, PSNRmean=%f, Phi09=%f, PSNRmax=%f, PhiPSNRmax=%f, Gain=%f\n',RCPC{i},PSNRmean,Phi09,PSNRmax,PhiPSNRmax,gains(i)); 41 | line('Parent',gca,'XData',xdat,'YData',PSNRcum,'Tag',RCPC{i},'LineStyle',ls{i},'LineWidth',lw{i},'Color',lb{i}); 42 | PSNRmeans(i)=PSNRmean; 43 | Phi09s(i)=Phi09; 44 | PSNRmaxs(i)=PSNRmax; 45 | PhiPSNRmaxs(i)=PhiPSNRmax; 46 | end; 47 | assignin('base','PSNRmean',PSNRmeans); 48 | assignin('base','gain',gains); 49 | assignin('base','Phi09',Phi09s); 50 | assignin('base','PSNRmax',PSNRmaxs); 51 | assignin('base','PhiPSNRmax',PhiPSNRmaxs); 52 | 53 | set(ah,'YLim',[floor(minPSNR) ceil(maxPSNR)]); 54 | legend(RCPC{1},RCPC{2},RCPC{3},RCPC{4},RCPC{5},RCPC{6},RCPC{7},RCPC{8},RCPC{9},RCPC{10}); 55 | 56 | figure('Position',[1 scnsize(4)/4 scnsize(3) 2*scnsize(4)/5]); 57 | bh=axes('XLim',[1 10],'YLim',[floor(min(PSNRmeans)) ceil(max(PSNRmeans))],'Box','on','FontSize',14,'XGrid','on','XTick',1:10,'XTickLabel',RCPC,'Position',[0.1300 0.2100 0.7750 0.7150]); 58 | ylabel('{\itPSNR} [dB]','FontName','Times New Roman','FontSize',24); 59 | xlabel('RCPC kod','FontName','Times New Roman','FontSize',24); 60 | line('Parent',bh,'XData',1:10,'YData',PSNRmeans,'LineStyle','-','LineWidth',2,'Color','k'); 61 | h=axes('Position',[0 0 1 1],'Visible','off','XLim',[0 1],'YLim',[0 1]); %dummy axes 62 | line('Parent',h,'XData',[0.061035 0.061035],'YData',[0.57915 0.36091]); 63 | 64 | if any(gains) 65 | figure('Position',[1 scnsize(4)/4 scnsize(3) 2*scnsize(4)/5]); 66 | bh=axes('XLim',[1 10],'YLim',[floor(min(gains)) ceil(max(gains))],'Box','on','FontSize',14,'XGrid','on','XTick',1:10,'XTickLabel',RCPC,'Position',[0.1300 0.2100 0.7750 0.7150]); 67 | ylabel('{\itg} [dB]','FontName','Times New Roman','FontSize',24); 68 | xlabel('RCPC kod','FontName','Times New Roman','FontSize',24); 69 | line('Parent',bh,'XData',1:10,'YData',gains,'LineStyle','-','LineWidth',2,'Color','k'); 70 | end; 71 | -------------------------------------------------------------------------------- /JSCCImage/send_image_equal.m: -------------------------------------------------------------------------------- 1 | function [PSNR,PSNRmean,PSNRcum,Phi09,PhiPSNRmax,PSNRmax]=send_image_equal(imgname,trans_time,chnlname,PunctRate,hmany,gain) 2 | 3 | PSNR=0;PSNRmean=0;PSNRcum=0;Phi09=0;PhiPSNRmax=0;PSNRmax=0; 4 | CRC_siz=16; 5 | A=imread(imgname); 6 | %get the parameters of the selected channel 7 | [ch_handle,parametar]=get_channel(chnlname); 8 | parametar.gain=gain; 9 | packet_siz=parametar.Nch; 10 | %compute parameters of the selected RCPC code 11 | [Memory,Ib,Kb,t,PN,P,TotRate,PunctInd]=get_RCPC_code(PunctRate); 12 | fprintf('Mother code rate: 1/%d\n',PN/P); 13 | fprintf('Puncturing code rate: %d/%d\n',length(PunctInd),PN); 14 | fprintf('Total rate: %d/%d\n',Ib,Kb); 15 | [PunctIndFull,PacketData,DepunctLen]=Punct_Variables(Memory,Ib,Kb,PN,P,PunctInd,packet_siz,CRC_siz); 16 | channel_bits=(parametar.Bch*trans_time)/1000; 17 | fprintf('Computed channel bits: %f\n',channel_bits); 18 | num_packets=floor(channel_bits/packet_siz); %number of packets that satisfy the time condition 19 | Av_channel_bits=num_packets*packet_siz; 20 | fprintf('Available channel bits: %f\n',Av_channel_bits); 21 | fprintf('Data bits per packet: %f\n',PacketData); 22 | data_bits=PacketData*num_packets; 23 | bpp=data_bits/numel(A); 24 | fprintf('Effective bpp: %f\n',bpp); 25 | %compute the actual bitstream 26 | bpp_byte=8*ceil(data_bits/8)/numel(A); 27 | N=log2(size(A,1))-2; 28 | [Arec,bitstream,PSNR,MSE,D,Drec,s,p_stream]=spiht_wpackets(A,bpp_byte,'CDF_9x7',N); 29 | InputStream=bitstream(1,1:data_bits); 30 | %load the pre-computed byte-precision R-D curve 31 | [pathstr,filename]=fileparts(imgname); 32 | load([filename 'RD'],'PSNR_RD8','MSE_RD8'); 33 | 34 | MSEuk=0; 35 | for j=1:hmany 36 | fprintf('%d\n',j); 37 | DetectedErr=0; 38 | CRCDetErr=0; 39 | for i=1:num_packets 40 | InPckt=InputStream((i-1)*PacketData+1:i*PacketData); 41 | CRC=generic_crc(InPckt,CRC_siz); 42 | %Convolutional encoding + puncturing 43 | OutputStreamPunct=RCPC_encode([CRC InPckt],Memory,t,P,PunctIndFull); % OutputStreamPunct is bipolar!! 44 | [OutputStreamPunctCh,parametar]=feval(ch_handle,OutputStreamPunct,parametar); %Power of the signal is now 1, i.e. 0dBW 45 | %Viterbi decoding 46 | CRCOutPckt=RCPC_decode(OutputStreamPunctCh,Memory,t,PunctIndFull,DepunctLen,PacketData+CRC_siz); 47 | OutPckt=CRCOutPckt(CRC_siz+1:end); 48 | if CRC_siz>0 %check CRC 49 | CRC=CRCOutPckt(1:CRC_siz); 50 | CRCerr=any(generic_crc(OutPckt,CRC_siz)~=CRC); 51 | DetectedErr=DetectedErr+CRCerr; 52 | end; 53 | if DetectedErr break;end; 54 | end; 55 | if ~DetectedErr i=i+1;end; 56 | ind=floor(((i-1)*PacketData)/8); 57 | if ind==0 ind=1;end; 58 | MSE(j)=MSE_RD8(ind); 59 | PSNR(j)=PSNR_RD8(ind); 60 | fprintf('PSNR = %f\n',PSNR(j)); 61 | MSEuk=MSEuk+MSE(j); 62 | parametar.state=-1; 63 | end; 64 | PSNRmean=10*log10(255^2/(MSEuk/hmany)); 65 | PSNRcum=fliplr(sort(PSNR)); 66 | fprintf('mean PSNR = %f\n',PSNRmean); 67 | Phi09=PSNRcum(round(hmany*0.9)); 68 | fprintf('Phi-1(0.9) = %f\n',Phi09); 69 | PSNRmax=PSNR_RD8(floor((data_bits)/8)); 70 | fprintf('PSNRmax = %f\n', PSNRmax); 71 | PhiPSNRmax=sum(PSNRcum==PSNRmax)/hmany; 72 | fprintf('Phi(PSNRmax) =%f\n',PhiPSNRmax); -------------------------------------------------------------------------------- /JSCCImage/send_image_equal_RS.m: -------------------------------------------------------------------------------- 1 | function [PSNR,PSNRmean,PSNRcum,Phi09,PhiPSNRmax,PSNRmax]=send_image_equal_RS(imgname,trans_time,chnlname,PunctRate,hmany,gain,dps,RSsyms) 2 | 3 | PSNR=0;PSNRmean=0;PSNRcum=0;Phi09=0;PhiPSNRmax=0;PSNRmax=0; 4 | CRC_siz=16; 5 | dps=15; 6 | A=imread(imgname); 7 | %get the parameters of the selected channel 8 | [ch_handle,parametar]=get_channel(chnlname); 9 | parametar.gain=gain; 10 | packet_siz=parametar.Nch; 11 | Ni=floor((1/dps)/(packet_siz/parametar.Bch)); 12 | 13 | %compute parameters of the selected RCPC code 14 | [Memory,Ib,Kb,t,PN,P,TotRate,PunctInd]=get_RCPC_code(PunctRate); 15 | fprintf('Mother code rate: 1/%d\n',PN/P); 16 | fprintf('Puncturing code rate: %d/%d\n',length(PunctInd),PN); 17 | fprintf('Total rate: %d/%d\n',Ib,Kb); 18 | [PunctIndFull,PacketData,DepunctLen]=Punct_Variables(Memory,Ib,Kb,PN,P,PunctInd,packet_siz,CRC_siz); 19 | PacketUnused=mod(PacketData,8); %solve this!! 20 | PacketData=PacketData-PacketUnused; 21 | PacketBytes=PacketData/8; 22 | Unusedbits=zeros(1,PacketUnused); 23 | channel_bits=(parametar.Bch*trans_time)/1000; 24 | fprintf('Computed channel bits: %f\n',channel_bits); 25 | num_packets=floor(channel_bits/packet_siz); %number of packets that satisfy the time condition 26 | last_pckts=mod(num_packets,Ni); 27 | data_per_intlvd=Ni-RSsyms; 28 | last_RS_packet=floor(num_packets/Ni)*data_per_intlvd; 29 | data_Packets=last_RS_packet+last_pckts; 30 | Av_channel_bits=num_packets*packet_siz; 31 | fprintf('Available channel bits: %f\n',Av_channel_bits); 32 | fprintf('Data bits per packet: %f\n',PacketData); 33 | data_bits=PacketData*data_Packets; 34 | bpp=data_bits/numel(A); 35 | fprintf('Effective bpp: %f\n',bpp); 36 | %compute the actual bitstream 37 | bpp_byte=8*ceil(data_bits/8)/numel(A); 38 | N=log2(size(A,1))-2; 39 | [Arec,bitstream,PSNR,MSE,D,Drec,s,p_stream]=spiht_wpackets(A,bpp_byte,'CDF_9x7',N); 40 | InputStream=bitstream(1,1:data_bits); 41 | %load the pre-computed byte-precision R-D curve 42 | [pathstr,filename]=fileparts(imgname); 43 | load([filename 'RD'],'PSNR_RD8','MSE_RD8'); 44 | 45 | errpckt=zeros(1,num_packets); 46 | InPckts=zeros(1,PacketData*Ni); 47 | MSEuk=0; 48 | RSindices=data_per_intlvd*PacketData+1:Ni*PacketData; 49 | for j=1:hmany 50 | fprintf('%d\n',j); 51 | DetectedErr=0; 52 | RSsymbols=RSsyms; 53 | data_per_intlvd=Ni-RSsyms; 54 | Ni_cur=Ni; 55 | for i=1:data_per_intlvd:data_Packets 56 | if i>=last_RS_packet 57 | data_per_intlvd=data_Packets-i+1; 58 | RSsymbols=0; 59 | Ni_cur=data_per_intlvd; 60 | end; %last packets are reached 61 | InPckts(1:data_per_intlvd*PacketData)=InputStream((i-1)*PacketData+1:(i+data_per_intlvd-1)*PacketData); 62 | if RSsymbols 63 | %InPcktsInt=bi2de(reshape(InPckts,[8 length(InPckts)/8])'); 64 | %InPcktsGF=reshape(InPcktsInt,[PacketBytes data_per_intlvd]); 65 | %msg=gf(InPcktsGF,8); 66 | %RScoded=rsenc(msg,Ni,data_per_intlvd); 67 | %de2bi(double(RScoded')) 68 | InPckts(RSindices)=randint(length(RSindices),1,2)'; %heh, only simulation of RS -> fooled ya!! 69 | end; 70 | OutputStreamPunct=zeros(1,data_per_intlvd*packet_siz); %(data_per_intlvd,packet_siz) 71 | for k=0:Ni_cur-1 72 | InPckt=InPckts(k*PacketData+1:(k+1)*PacketData); 73 | CRC=generic_crc(InPckt,CRC_siz); 74 | %Convolutional encoding + puncturing 75 | OutputStreamPunct(1,k*packet_siz+1:(k+1)*packet_siz)=RCPC_encode([CRC InPckt Unusedbits],Memory,t,P,PunctIndFull); % OutputStreamPunct is bipolar!! 76 | end; 77 | [OutputStreamPunctCh,parametar]=feval(ch_handle,OutputStreamPunct,parametar); %Power of the signal is now 1, i.e. 0dBW 78 | OutputStreamPunctCh=reshape(OutputStreamPunctCh,packet_siz,Ni_cur)'; %reshape 79 | numCRCerr=0; 80 | DetectedErr=0; 81 | for k=0:Ni_cur-1 82 | %Viterbi decoding 83 | CRCOutPckt=RCPC_decode(OutputStreamPunctCh(k+1,:),Memory,t,PunctIndFull,DepunctLen,PacketData+CRC_siz); 84 | OutPckt=CRCOutPckt(CRC_siz+1:end); 85 | if CRC_siz>0 %check CRC 86 | CRC=CRCOutPckt(1:CRC_siz); 87 | CRCerr=any(generic_crc(OutPckt,CRC_siz)~=CRC); 88 | end; 89 | %RS decode using erasures simulation -> fooled ya!! 90 | if CRCerr 91 | numCRCerr=numCRCerr+1; 92 | if numCRCerr==1 93 | firstCRCerr=k; 94 | end; 95 | if numCRCerr>RSsymbols 96 | DetectedErr=1; 97 | k=firstCRCerr; 98 | break; 99 | end; 100 | end; 101 | end; 102 | if DetectedErr 103 | break; 104 | end; 105 | end; 106 | if ~DetectedErr k=k+1;end; 107 | ind=((i-1+k)*PacketData)/8; 108 | if ind==0 ind=1;end; 109 | MSE(j)=MSE_RD8(ind); 110 | PSNR(j)=PSNR_RD8(ind); 111 | fprintf('PSNR = %f\n',PSNR(j)); 112 | MSEuk=MSEuk+MSE(j); 113 | end; 114 | 115 | PSNRmean=10*log10(255^2/(MSEuk/hmany)); 116 | PSNRcum=fliplr(sort(PSNR)); 117 | fprintf('mean PSNR = %f\n',PSNRmean); 118 | Phi09=PSNRcum(round(hmany*0.9)); 119 | fprintf('Phi-1(0.9) = %f\n',Phi09); 120 | PSNRmax=PSNR_RD8(floor((data_bits)/8)); 121 | fprintf('PSNRmax = %f\n', PSNRmax); 122 | PhiPSNRmax=sum(PSNRcum==PSNRmax)/hmany; 123 | fprintf('Phi(PSNRmax) =%f\n',PhiPSNRmax); -------------------------------------------------------------------------------- /JSCCImage/send_image_unequal.m: -------------------------------------------------------------------------------- 1 | function [PSNR,PSNRmean,PSNRcum,Phi09,PhiPSNRmax,PSNRmax]=send_image_unequal(imgname,trans_time,chnlname,RDfile,hmany,gain) 2 | 3 | RCPC{1}='1/1'; 4 | RCPC{2}='8/9'; 5 | RCPC{3}='4/5'; 6 | RCPC{4}='2/3'; 7 | RCPC{5}='4/7'; 8 | RCPC{6}='1/2'; 9 | RCPC{7}='4/9'; 10 | RCPC{8}='2/5'; 11 | RCPC{9}='4/11'; 12 | RCPC{10}='1/3'; 13 | PSNR=0;PSNRmean=0;PSNRcum=0;Phi09=0;PhiPSNRmax=0;PSNRmax=0; 14 | CRC_siz=16; 15 | A=imread(imgname); 16 | %get the parameters of the selected channel 17 | [ch_handle,parametar]=get_channel(chnlname); 18 | parametar.gain=gain; 19 | packet_siz=parametar.Nch; 20 | %compute unequal protection scheme 21 | 22 | [unequal_RCPC,unequal_data_bits]=optimal_RCPC_unequal(trans_time,CRC_siz,chnlname,RDfile,'no_draw'); 23 | for i=1:10 24 | [Memory,Ib,Kb,t,PN,P,TotRate,PunctInd]=get_RCPC_code(RCPC{i}); 25 | [PunctIndFull{i},PacketData,DepunctLen{i}]=Punct_Variables(Memory,Ib,Kb,PN,P,PunctInd,packet_siz,CRC_siz); 26 | end; 27 | channel_bits=(parametar.Bch*trans_time)/1000; 28 | fprintf('Computed channel bits: %f\n',channel_bits); 29 | num_packets=floor(channel_bits/packet_siz); %number of packets that satisfy the time condition 30 | Av_channel_bits=num_packets*packet_siz; 31 | fprintf('Available channel bits: %f\n',Av_channel_bits); 32 | 33 | data_bits=sum(unequal_data_bits); 34 | cum_bits=[1 cumsum(unequal_data_bits)]; 35 | bpp=data_bits/numel(A); 36 | fprintf('Effective bpp: %f\n',bpp); 37 | %compute the actual bitstream 38 | bpp_byte=8*ceil(data_bits/8)/numel(A); 39 | N=log2(size(A,1))-2; 40 | [Arec,bitstream,PSNR,MSE,D,Drec,s,p_stream]=spiht_wpackets(A,bpp_byte,'CDF_9x7',N); 41 | InputStream=bitstream(1,1:data_bits); 42 | 43 | %load the pre-computed byte-precision R-D curve 44 | [pathstr,filename]=fileparts(imgname); 45 | load([filename 'RD'],'PSNR_RD8','MSE_RD8'); 46 | 47 | MSEuk=0; 48 | for j=1:hmany 49 | fprintf('%d\n',j); 50 | DetectedErr=0; 51 | CRCDetErr=0; 52 | for i=1:num_packets 53 | InPckt=InputStream(cum_bits(i):cum_bits(i)+unequal_data_bits(i)-1); 54 | CRC=generic_crc(InPckt,CRC_siz); 55 | %Convolutional encoding + puncturing 56 | OutputStreamPunct=RCPC_encode([CRC InPckt],Memory,t,P,PunctIndFull{unequal_RCPC(i)}); % OutputStreamPunct is bipolar!! 57 | %AWGN channel - @awgn_EsN0 function 58 | %BSC channel - @BSC_BER function 59 | 60 | [OutputStreamPunctCh,parametar]=feval(ch_handle,OutputStreamPunct,parametar); %Power of the signal is now 1, i.e. 0dBW 61 | %Viterbi decoding 62 | CRCOutPckt=RCPC_decode(OutputStreamPunctCh,Memory,t,PunctIndFull{unequal_RCPC(i)},DepunctLen{unequal_RCPC(i)},unequal_data_bits(i)+CRC_siz); 63 | OutPckt=CRCOutPckt(CRC_siz+1:end); 64 | if CRC_siz>0 %check CRC 65 | CRC=CRCOutPckt(1:CRC_siz); 66 | CRCerr=any(generic_crc(OutPckt,CRC_siz)~=CRC); 67 | DetectedErr=DetectedErr+CRCerr; 68 | end; 69 | if DetectedErr break;end; 70 | end; 71 | if ~DetectedErr i=i+1;end; 72 | ind=floor((cum_bits(i))/8); 73 | if ind==0 ind=1;end; 74 | MSE(j)=MSE_RD8(ind); 75 | PSNR(j)=PSNR_RD8(ind); 76 | fprintf('PSNR = %f\n',PSNR(j)); 77 | MSEuk=MSEuk+MSE(j); 78 | parametar.state=-1; 79 | end; 80 | PSNRmean=10*log10(255^2/(MSEuk/hmany)); 81 | PSNRcum=fliplr(sort(PSNR)); 82 | fprintf('mean PSNR = %f\n',PSNRmean); 83 | Phi09=PSNRcum(round(hmany*0.9)); 84 | fprintf('Phi-1(0.9) = %f\n',Phi09); 85 | PSNRmax=PSNR_RD8(floor((data_bits)/8)); 86 | fprintf('PSNRmax = %f\n', PSNRmax); 87 | PhiPSNRmax=sum(PSNRcum==PSNRmax)/hmany; 88 | fprintf('Phi(PSNRmax) =%f\n',PhiPSNRmax); 89 | 90 | 91 | -------------------------------------------------------------------------------- /Jpeg2000/Jpeg2000gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Jpeg2000/Jpeg2000gui.png -------------------------------------------------------------------------------- /Jpeg2000/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Nikola Sprljan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Jpeg2000/README.md: -------------------------------------------------------------------------------- 1 | JPEG2000 Toolbox 2 | ================ 3 | 4 | A GUI front-end for executing the external JPEG2000 software (the java-based, not included in this package). Apart form the GUI, the script jpeg2000jj2k.m can be used for calling JJ2000 in the command line mode. The scripts for batch execution of the [JPEG 2000 Kakadu software](http://www.kakadusoftware.com/) are also provided (not included in this package). The only implementation of JJ2000 that currently can be found on the web is at [this link](http://anabuilder.free.fr/jj2000-5.1.jar). However, keep in mind this is not the original location, as the authors' location for dowload is not online any more ([original location](http://jj2000.epfl.ch/jj_download/index.html)) 5 | 6 | There is also this [Google code page](http://code.google.com/p/jj2000/), but you have to build the project yourself. 7 | 8 | 9 | Functions 10 | --------- 11 | 12 | - **jpeg2000gui** - GUI for Jpeg 2000 compression, calls jpeg2000jj2k 13 | - **jpeg2000jj2k** - Wrapper for running the JJ2000 java byte code (instructions to download java byte code provided) 14 | - **jpeg2000kakadu** - Wrappper for running the Kakadu JPEG 2000 binaries (instructions to download binaries provided) 15 | - **jpeg2000kakadu_yuv** - Script for the Kakadu JPEG 2000 compression of video sequences in YUV format 16 | 17 | Examples 18 | -------- 19 | Kakadu JPEG 2000 compression at 5 bit-rates with **jpeg2000kakadu**: 20 | 21 | >> [Arec,PSNR,bpp_out] = jpeg2000kakadu('Lena512.png',4,0.25:0.25:1.25,1,'parse',1); 22 | 1. bitrate 0.253357 bpp (0.253357 bpp): 23 | MSE (Mean Squared Error) = 85.891251 24 | PSNR (Peak Signal / Noise Ratio) = 28.791314 dB 25 | 2. bitrate 0.503357 bpp (0.503357 bpp): 26 | MSE (Mean Squared Error) = 49.897293 27 | PSNR (Peak Signal / Noise Ratio) = 31.150034 dB 28 | 3. bitrate 0.753357 bpp (0.753357 bpp): 29 | MSE (Mean Squared Error) = 19.818527 30 | PSNR (Peak Signal / Noise Ratio) = 35.160090 dB 31 | 4. bitrate 1.003357 bpp (1.003387 bpp): 32 | MSE (Mean Squared Error) = 9.743835 33 | PSNR (Peak Signal / Noise Ratio) = 38.243504 dB 34 | 5. bitrate 1.253357 bpp (1.253387 bpp): 35 | MSE (Mean Squared Error) = 0.636932 36 | PSNR (Peak Signal / Noise Ratio) = 50.089870 dB 37 | 38 | Compressing a raw (uncompressed) video with **jpeg2000kakadu\_yuv**: 39 | 40 | >> PSNR=jpeg2000kakadu_yuv('RaceHorses_416x240_30.yuv',[416 240],30,[1024 2048],5); 41 | Processing frame 1 42 | . Rate = 0.34228 bpp, PSNR_Y = 28.69, PSNR_U = 32.49, PSNR_V = 32.54 43 | . Rate = 0.68416 bpp, PSNR_Y = 32.19, PSNR_U = 35.29, PSNR_V = 35.40 44 | Processing frame 2 45 | . Rate = 0.34228 bpp, PSNR_Y = 28.87, PSNR_U = 32.39, PSNR_V = 33.00 46 | . Rate = 0.68416 bpp, PSNR_Y = 32.39, PSNR_U = 35.30, PSNR_V = 35.58 47 | Processing frame 3 48 | . Rate = 0.34228 bpp, PSNR_Y = 28.99, PSNR_U = 33.13, PSNR_V = 32.57 49 | . Rate = 0.68416 bpp, PSNR_Y = 32.55, PSNR_U = 35.22, PSNR_V = 35.65 50 | Processing frame 4 51 | . Rate = 0.34228 bpp, PSNR_Y = 29.22, PSNR_U = 33.04, PSNR_V = 32.96 52 | . Rate = 0.68416 bpp, PSNR_Y = 32.69, PSNR_U = 35.79, PSNR_V = 35.87 53 | Processing frame 5 54 | . Rate = 0.34228 bpp, PSNR_Y = 29.25, PSNR_U = 33.30, PSNR_V = 32.93 55 | . Rate = 0.68416 bpp, PSNR_Y = 32.73, PSNR_U = 35.68, PSNR_V = 35.67 56 | 57 | Wrapper for JJ2000 java implementation of JPEG2000, **jpeg2000jj2k**: 58 | 59 | >> [Arec,PSNR]=jpeg2000('Lena256.png',[0.1 0.5 1],1); 60 | Target bitrate = 1.0 bpp (i.e. 8192 bytes) 61 | Achieved bitrate = 0.9766846 bpp (i.e. 8001 bytes) 62 | [INFO]: 1 component(s) in codestream, 1 tile(s) 63 | Image dimension: 256x256 64 | Target rate = 0.1 bpp (819 bytes) 65 | Actual bitrate = 0.095214844 bpp (i.e. 780 bytes) 66 | [INFO]: 1 component(s) in codestream, 1 tile(s) 67 | Image dimension: 256x256 68 | Target rate = 0.5 bpp (4096 bytes) 69 | Actual bitrate = 0.4984131 bpp (i.e. 4083 bytes) 70 | [INFO]: 1 component(s) in codestream, 1 tile(s) 71 | Image dimension: 256x256 72 | Target rate = 1.0 bpp (8192 bytes) 73 | Actual bitrate = 0.9766846 bpp (i.e. 8001 bytes) 74 | >> image_show(Arec{1},256,1,''); 75 | >> image_show(Arec{2},256,1,''); 76 | >> image_show(Arec{3},256,1,''); 77 | 78 | Screenshot of **jpeg2000gui**: 79 | 80 | ![jpeg2000gui screenshot](https://github.com/nsprljan/ImageCodingResearchTools/raw/master/Jpeg2000/Jpeg2000gui.png) -------------------------------------------------------------------------------- /Jpeg2000/jpeg2000gui.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Jpeg2000/jpeg2000gui.fig -------------------------------------------------------------------------------- /Jpeg2000/jpeg2000jj2k.m: -------------------------------------------------------------------------------- 1 | function [Arec,PSNR]=jpeg2000jj2k(A,bpp,outf) 2 | %Wrapper for running the JJ2000 java byte code 3 | %[Arec,PSNR]=jpeg2000jj2k(A,bpp,outf) 4 | % 5 | %Input: 6 | % A - array containing the original image or its filename 7 | % bpp - vector of target decoding bitrates (bpp=bits per pixel) 8 | % outf - [optional, default = 0] if outf is not 0 the results will be 9 | % saved into files 10 | % 11 | %Output: 12 | % Arec - reconstructed images as a cell variable 13 | % 14 | %Note: 15 | % *WARNING* Place the required jar file in this toolbox directory! 16 | % Colour images are supported. 17 | % VJVM has to be installed on the machine, see e.g.: 18 | % http://www.java.com/en/download/manual.jsp 19 | % 20 | %Uses: 21 | % -The only implementation of JJ2000 that currently can be found on the web 22 | % is at http://anabuilder.free.fr/jj2000-5.1.jar 23 | % However this is not the original location, as the authors' location for 24 | % dowload is not online any more: http://jj2000.epfl.ch/jj_download/index.html 25 | % -iq_measures.m (Quality Assessment Toolbox) 26 | % 27 | %Example: 28 | % Arec=jpeg2000jj2k(A,0.1,0); 29 | % [Arec,PSNR]=jpeg2000jj2k('Lena256.png',[0.1 0.5 1],1); 30 | % 31 | %Java calling examples: 32 | % javaaddpath(fullfile(pwd,'jj2000-4.1.jar')) 33 | % javaclasspath 34 | % methods JJ2KEncoder -full 35 | % methodsview JJ2KEncoder 36 | % javaMethod('JJ2KEncoder.main') 37 | % JJ2KEncoder.main({'-i','pict.pgm','-o','out.j2k','-rate','2'}) 38 | 39 | Arec = {[]}; 40 | jj2000jar = 'jj2000-5.1.jar'; %replace with the jar file available 41 | if (exist(jj2000jar) ~=2) 42 | disp(sprintf(['Error: The file ' jj2000jar ' is not on the path, the program cannot be performed!'])); 43 | disp(sprintf('JJ2000 can be downloaded from http://jj2000.epfl.ch')); 44 | return 45 | end; 46 | if (exist('iq_measures.m') ~= 2) 47 | disp(sprintf('Warning: The function iq_measures.m is not on the path, the PSNR computation will not be performed!')); 48 | disp(sprintf('Function iq_measures.m is a part of Quality Assessment Toolbox')); 49 | end; 50 | if nargin<3 51 | outf=0; 52 | end; 53 | %init java 54 | p=javaclasspath; 55 | jjpath = fullfile(pwd,jj2000jar); 56 | jjex = 0; 57 | for i=1:length(p) 58 | jjex = jjex || strcmp(jjpath,p{i}); 59 | end 60 | if (~jjex) 61 | javaaddpath(jjpath); 62 | end; 63 | %init the rest 64 | n=size(bpp,2); 65 | maxbpp=max(bpp); 66 | direktorij=fileparts(which(mfilename)); 67 | compclr=1; 68 | if ~isstr(A) 69 | A=uint8(A); 70 | ext='.pgm'; 71 | else 72 | imf=imfinfo(A); 73 | if imf.BitDepth==8 74 | ext='.pgm'; 75 | elseif imf.BitDepth==24 76 | ext='.ppm'; 77 | compclr = 3; 78 | end; 79 | %fprintf(' Original image bitrate: %d bpp\n',imf.BitDepth); 80 | A=imread(A); 81 | end; 82 | PSNR = zeros(n,compclr); 83 | imedat='pict'; 84 | fullimedat=[imedat ext]; 85 | imwrite(A,fullimedat); 86 | %compression 87 | imekod=[imedat '_JJ2_' num2str(maxbpp) '.j2k']; 88 | JJ2KEncoder.main({'-i',fullimedat,'-o',imekod,'-rate',num2str(maxbpp)}); 89 | %delete temporay image 90 | delete(fullimedat); 91 | %decompression loop 92 | for i=1:n 93 | strbpp=strrep(num2str(bpp(i)),'.',''); 94 | imeprvo=imedat(1); 95 | imevan=[imeprvo '_' strbpp]; 96 | if size(imevan,2)>8 97 | imevan=imevan(1:8); 98 | end; 99 | fullimevan=[imevan ext]; 100 | JJ2KDecoder.main({'-i',imekod,'-o',fullimevan,'-rate',num2str(bpp(i))}); 101 | if outf 102 | Arec{i}=fullimevan; 103 | else 104 | Arec{i}=imread(fullimevan); 105 | delete(fullimevan); 106 | end; 107 | [MSE,PSNR(i,:)]=iq_measures(A,Arec{i}); 108 | end; 109 | %delete(imekod); %for some reason the file cannot be closed nor deleted 110 | -------------------------------------------------------------------------------- /Jpeg2000/jpeg2000kakadu.m: -------------------------------------------------------------------------------- 1 | function [Arec,PSNR,bpp_out] = jpeg2000kakadu(image,bpp,decbpp,res,mode,inchead,varargin) 2 | %Wrappper for running the Kakadu JPEG 2000 binaries 3 | %[Arec,PSNR,bpp_out]=jpeg2000kakadu(image,bpp,decbpp,res,mode,inchead,varargin) 4 | % 5 | %Input: 6 | % image - matrix or name of the input image 7 | % bpp - vector of target bitrates 8 | % decbpp - vector of bitrates for decompression 9 | % res - defines reduction of resolution (0 for the original resolution) 10 | % mode - selects mode of compression/decompression: 'truncate', 'parse' or 11 | % 'transcode' 12 | % inchead - include header size or not (1 for yes, 0 for no). What is meant is 13 | % whether some parts of the header are included in the input bitrate 14 | % or not. Kakadu specifies the rates that correspond to the resulting 15 | % .j2c complete file sizes, but in some cases we might be interested 16 | % only in the pure non-header part of the bit-stream. 17 | % -if inchead == 1 then the fixed part of the header (total length 18 | % minus the lenght of the header comment) is included in the input 19 | % bit-rate. In other words, the bit-rate corresponding to the length 20 | % of the comment (110 bytes) is added to the input bit-rate since it 21 | % is the only part of the header that I did not want to be included. 22 | % -if inchead == 1 then the bit-rate includes only the image data part 23 | % of the bit-stream. The whole header is added to the bit-rate, so 24 | % the Kakadu does not include it in the bit-rate of the image data 25 | % part of the bit-stream. 26 | % varargin - aditional parameters 27 | % 28 | %Output: 29 | % Arec - output image (only for the maximum bitrate) 30 | % PSNR - vector of PSNR values for decode bitrates 31 | % bpp_out - output bpp (when lower quality/resolution part is extracted 32 | % from the compressed bit stream) 33 | %Note: 34 | % *WARNING* Place the required binaries under ./kakadu directory! 35 | % The location of the JPEG-2000 binaries is specified with the variable 36 | % 'binpath'. The other variables specify the binaries' filenames. 37 | % The expected YUV subsampling format is 4:2:0. 38 | % I am not sure though if the constants used for inchead are still valid as I 39 | % have switched to the new version of Kakadu at some point but have not changed 40 | % that part of the code. 41 | % 42 | %Uses: 43 | % kdu_compress.exe, kdu_transcode.exe, kdu_expand.exe, kdu_v(version).dll 44 | % ((c) David Taubman http://www.kakadusoftware.com/) Version 4.0.3 required 45 | % for selecting the option 'parse'. 46 | % 47 | % iq_measures.m (Quality Assessment toolbox) 48 | % wavelet_downscale.m (Wavelet toolbox) 49 | % 50 | %Examples: 51 | % [Arec,PSNR,bpp_out] = jpeg2000kakadu('Lena512.png',1,1,0,'parse',1); 52 | % [Arec,PSNR,bpp_out] = jpeg2000kakadu('Lena512.png',4,0.25:0.25:1.25,1,'parse',1); 53 | % [Arec,PSNR,bpp_out] = jpeg2000kakadu('Lena512.png',1,0.1:0.1:1,0,'transcode',0); 54 | 55 | scriptpath=fileparts(which(mfilename)); %in which directory is this m-file 56 | %%%SWITCHES%%% 57 | binpath = [scriptpath '\kakadu']; 58 | KDUenc = [binpath '\kdu_compress.exe']; 59 | KDUtrans = [binpath '\kdu_transcode.exe']; 60 | KDUdec = [binpath '\kdu_expand.exe']; 61 | %%%%%%%%%%%%% 62 | fid = fopen(KDUenc); 63 | if (fid == -1) error('Kakadu encoder executable not found!');end; 64 | fclose(fid); 65 | fid = fopen(KDUdec); 66 | if (fid == -1) error('Kakadu decoder executable not found!');end; 67 | fclose(fid); 68 | fid = fopen(KDUtrans); 69 | if (fid == -1) error('Kakadu transcoder executable not found!');end; 70 | fclose(fid); 71 | KDUenc=['"' KDUenc '"']; 72 | KDUtrans=['"' KDUtrans '"']; 73 | KDUdec=['"' KDUdec '"']; 74 | 75 | if isstr(image) %if variable image is a string then it refers to the image file 76 | A=imread(image); 77 | else %otherwise variable image is a matrix 78 | if strcmp(class(image),'double') 79 | A=uint8(round(image)); 80 | else 81 | A=image; 82 | end; 83 | end; 84 | imwrite(A,'image.bmp'); 85 | s=size(A);numpix=s(1)*s(2); 86 | if ~inchead 87 | header_size=288*8; %bits 88 | else %exclude only the comment segment 89 | header_size=110*8; %bits 90 | end; 91 | addbpp=header_size/numpix; 92 | bpp=bpp+addbpp; 93 | hddecbpp=decbpp+addbpp; 94 | if ~isempty(varargin) 95 | adit=varargin{1}; 96 | else 97 | adit=[]; 98 | end; 99 | %computing the reference image 100 | compclr = size(A,3); 101 | if res>0 102 | if compclr>1 103 | Aref(:,:,1)=wavelet_downscale(A(:,:,1),'CDF_9x7',res); 104 | Aref(:,:,2)=wavelet_downscale(A(:,:,2),'CDF_9x7',res); 105 | Aref(:,:,3)=wavelet_downscale(A(:,:,3),'CDF_9x7',res); 106 | else 107 | Aref=wavelet_downscale(A,'CDF_9x7',res); 108 | end; 109 | else 110 | Aref=A; 111 | end; 112 | 113 | 114 | bppstr=num2str(bpp,'%0.6f,');bppstr(end)=[]; %remove the trailing ',' 115 | ratestr=[' -rate ' bppstr]; 116 | command=[KDUenc ' -i image.bmp -o image_compressed.j2c' ratestr ' -record compress_record.txt ' adit]; 117 | [c,w]=dos(command); 118 | % fid=fopen('image_compressed.j2c','r'); 119 | % [bitstream,byte_count] = fread(fid,'ubit8'); 120 | % fclose(fid); 121 | 122 | if strcmp(mode,'transcode') 123 | hddecbpp=hddecbpp*4^res; %to keep decoding bitrate consistent with the original image size 124 | end; 125 | for j=1:length(hddecbpp) 126 | outfilename=['image_decompressed' num2str(decbpp(j)) '.bmp']; 127 | switch mode 128 | case 'truncate' 129 | command=[KDUdec ' -i image_compressed.j2c -o ' outfilename ' -rate ' num2str(hddecbpp(j)) ' -reduce ' num2str(res)]; 130 | case 'parse' 131 | command=[KDUdec ' -i image_compressed.j2c -o ' outfilename ' -rate ' num2str(hddecbpp(j)) ' -simulate_parsing -reduce ' num2str(res)]; 132 | case 'transcode' 133 | command=[KDUtrans ' -i image_compressed.j2c -o image_transreduced.j2c -reduce ' num2str(res) ' -rate ' num2str(hddecbpp(j))]; 134 | end; 135 | [c,w]=dos(command); 136 | if c==-1 137 | error(['Error while decoding:' w]); 138 | end; 139 | strrows=strread(w,'%s','delimiter','\n'); %parse the message to find the size of extracted portion of the file 140 | switch mode 141 | case 'transcode' 142 | [bytes,bpp_realk]=strread(strrows{9},'Total bytes written = %d = %f bits/pel.'); 143 | command=[KDUdec ' -i image_transreduced.j2c -o ' outfilename]; 144 | [c,w]=dos(command); 145 | if c==-1 146 | error(['Error while decoding:' w]); 147 | end; 148 | otherwise 149 | [bytes,bpp_realk]=strread(strrows{3},'Code-stream bytes (excluding any file format) = %d = %f bits/pel.'); 150 | end; 151 | bpp_out(j)=8/(numpix/bytes); %original image is supposedly 8bpp 152 | if ~strcmp(mode,'transcode') 153 | fprintf('%d. bitrate %f bpp (%f bpp):\n',j,hddecbpp(j),bpp_out(j)); 154 | else 155 | fprintf('%d. bitrate %f bpp (%f bpp):\n',j,hddecbpp(j)/4^res,bpp_out(j)); 156 | end; 157 | Arec=imread(outfilename); 158 | [MSE(j,:),PSNR(j,:)]=iq_measures(Aref,Arec,'disp'); 159 | delete(outfilename); 160 | end; 161 | %comment these out to disable deleting 162 | delete('image.bmp'); 163 | delete('compress_record.txt'); 164 | delete('image_compressed.j2c'); -------------------------------------------------------------------------------- /Jpeg2000/jpeg2000kakadu_yuv.m: -------------------------------------------------------------------------------- 1 | function PSNR = jpeg2000kakadu_yuv(yuvfile,dims,fps,brates,numfrm) 2 | %Frontend for the Kakadu JPEG 2000 compression of video sequences in YUV format 3 | %PSNR = jpeg2000kakadu_yuv(yuvfile,dims,fps,brates,numfrm) 4 | % 5 | %Input: 6 | % yuvfile - YUV sequence file 7 | % dims - dimensions of the frame [width height] 8 | % fps - frames per second 9 | % brates - vector of target bitrates 10 | % numfrm - number of frames to read from a YUV file 11 | % 12 | %Output: 13 | % PSNR - 3D matrix with PSNR of the compressed YUV sequence, where the 14 | % distribution between dimensions is as follows: 15 | % PSNR(frame,target_layer,component) 16 | % 17 | %Note: 18 | % The location of the JPEG-2000 binaries is specified with the variable 19 | % 'binpath'. The other variables specify the binaries' filenames. 20 | % The expected YUV subsampling format is 4:2:0. 21 | % 22 | %Uses: 23 | % kdu_compress.exe, kdu_transcode.exe, kdu_expand.exe 24 | % ((c) David Taubman http://www.kakadusoftware.com/) 25 | % iq_measures.m (Quality Assessment toolbox) 26 | % yuv_export.m (YUV Toolbox) 27 | % save_yuvframe.m (YUV Toolbox) 28 | % 29 | %Examples: 30 | % PSNR=jpeg2000kakadu_yuv('CITY_704x576_60_orig_01.yuv',[704 576],60,[2048],2); 31 | % PSNR=jpeg2000kakadu_yuv('RaceHorses_416x240_30.yuv',[416 240],30,[1024 2048],10); 32 | 33 | scriptpath=fileparts(which(mfilename)); %in which directory is this m-file 34 | %%%SWITCHES%%% 35 | binpath = [scriptpath '\kakadu']; 36 | KDUenc = [binpath '\kdu_compress.exe']; 37 | KDUtrans = [binpath '\kdu_transcode.exe']; 38 | KDUdec = [binpath '\kdu_expand.exe']; 39 | KDUenc=['"' KDUenc '"']; 40 | KDUtrans=['"' KDUtrans '"']; 41 | KDUdec=['"' KDUdec '"']; 42 | outfileY = 'imageY.pgm'; 43 | outfileU = 'imageU.pgm'; 44 | outfileV = 'imageV.pgm'; 45 | j2cheaderbytes = 149; %to take into account header bytes from FF4F (start of 46 | %code-stream) and FF93 (start of data) markers 47 | %%%%%%%%%%%%% 48 | if (nargin < 5) %go to the starting frame 49 | numfrm = Inf; 50 | end; 51 | bpp = (brates * 1000 + j2cheaderbytes * 8)/(fps*prod(dims)); 52 | bppstrs = cell(numel(bpp),1); 53 | bppstr = []; 54 | for j = 1:numel(bpp) 55 | bppstrs{j} = num2str(bpp(j)); 56 | bppstr = [bppstr bppstrs{j} ',']; 57 | end; 58 | bppstr(end)=[]; 59 | YdimH = num2str(dims(1)); 60 | YdimW = num2str(dims(2)); 61 | UVdimH = num2str(floor(dims(1)/2)); 62 | UVdimW = num2str(floor(dims(2)/2)); 63 | dimstr = ['{' YdimW ',' YdimH '},{' UVdimW ',' UVdimH '},{' UVdimW ',' UVdimH '}']; 64 | i = 0; 65 | PSNR = zeros(numfrm,numel(bpp),3); 66 | MSE = zeros(numfrm,numel(bpp),3); 67 | while (i < numfrm) 68 | [s,Yo,Uo,Vo] = save_yuvframe(yuvfile,dims,i,'image'); 69 | i = i + 1; 70 | fprintf('Processing frame %d\n',i); 71 | command = [KDUenc ' -no_info -i imageY.raw,imageU.raw,imageV.raw -o image_compressed.jp2 -rate ',... 72 | bppstr ' -jp2_space sYCC Scomponents=3 Ssigned=no,no,no Sprecision=8,8,8 Sdims=',... 73 | dimstr ' Cycc=no CRGoffset={0,0},{0.25,0.25},{0.25,0.25}']; 74 | [c,w]=dos(command); 75 | if (c == -1) 76 | error(['Error while encoding:' w]); 77 | end; 78 | delete('imageY.raw');delete('imageU.raw');delete('imageV.raw'); 79 | for j=1:numel(bpp) 80 | outyuvfilename = ['j2k_' bppstrs{j} 'bpp_' yuvfile]; 81 | fprintf('.'); 82 | command = [KDUdec ' -i image_compressed.jp2 -o ' outfileY ',' outfileU ',' outfileV,... 83 | ' -rate ' bppstrs{j} ' -simulate_parsing -raw_components']; 84 | [c,w]=dos(command); 85 | if (c == -1) 86 | error(['Error while decoding:' w]); 87 | end; 88 | ArecY = imread(outfileY); 89 | ArecU = imread(outfileU); 90 | ArecV = imread(outfileV); 91 | delete(outfileY);delete(outfileU);delete(outfileV); 92 | [MSE(i,j,1), PSNR(i,j,1)] = iq_measures(Yo{1},ArecY); 93 | [MSE(i,j,2), PSNR(i,j,2)] = iq_measures(Uo{1},ArecU); 94 | [MSE(i,j,3), PSNR(i,j,3)] = iq_measures(Vo{1},ArecV); 95 | %if (i == 1) %delete the output yuv file if it exists 96 | % fopen(outyuvfilename,'w'); 97 | %end; 98 | yuv_export({ArecY},{ArecU},{ArecV},outyuvfilename,1); 99 | fprintf(' Rate = %s bpp, PSNR_Y = %.2f, PSNR_U = %.2f, PSNR_V = %.2f\n', bppstrs{j}, PSNR(i,j,1), PSNR(i,j,2), PSNR(i,j,3)); 100 | end; 101 | delete('image_compressed.jp2'); 102 | end; 103 | -------------------------------------------------------------------------------- /QualityAssessment/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Nikola Sprljan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /QualityAssessment/README.md: -------------------------------------------------------------------------------- 1 | MATLAB Quality Assessment Toolbox 2 | ================== 3 | 4 | Various reconstructed image quality metrics. Used in most of the other toolboxes. 5 | 6 | 7 | Functions 8 | --------- 9 | 10 | - **iq_measures** - Image Quality Measures - various measures of reconstructed image quality 11 | - **image_show** - Displays image, with additional parameters 12 | 13 | 14 | Examples 15 | -------- 16 | **iq\_measures**: 17 | 18 | >> A = imread('Lena256.png'); 19 | >> B = double(A) + rem(magic(256),5) - 2; 20 | >> [MSE,PSNR,AD,SC,NK,MD,LMSE,NAE] = iq_measures(A,B,'disp'); 21 | MSE (Mean Squared Error) = 1.999985 22 | PSNR (Peak Signal / Noise Ratio) = 45.120537 dB 23 | AD (Average Difference) = 0.000015 24 | SC (Structural Content) = 0.999893 25 | NK (Normalised Cross-Correlation) = 0.999997 26 | MD (Maximum Difference) = 2.000000 27 | LMSE (Laplacian Mean Squared Error) = 0.035148 28 | NAE (Normalised Absolute Error) = 0.009669 -------------------------------------------------------------------------------- /QualityAssessment/image_show.m: -------------------------------------------------------------------------------- 1 | function X=image_show(img,grlvls,scale,title) 2 | %Displays image, with additional parameters 3 | %X = image_show(img,grlvls,scale,title) 4 | % 5 | %Input: 6 | % img - image array; if the values fall outside [0,255] they will be 7 | % scaled 8 | % grlvls - if it is a single value it represents the number of gray levels 9 | % to be displayed; 10 | % if grlvls is an array then it represents the colormap 11 | % scale - scale for displaying the image 12 | % title - name of the image figure, if it starts with 'save_' the image will be 13 | % saved instead. Don't forget the image format(e.g. 'save_test.png')!! 14 | % 15 | %Output: 16 | % X - contains the image (useful if the image values have been scaled to 17 | % fit in the [0, 255] range 18 | % 19 | %Note: 20 | % Works also for truecolor non-indexed images. 21 | % If the range between the maximum and the minimum value in the image is larger 22 | % than 2^16 then the image values will be rescaled logarithmically. 23 | % 24 | %Example: 25 | % X = image_show(A,256,2,'A'); %zoom 2x 26 | 27 | %for wavelet coefficients: 28 | %Z2= 128+32*log2(abs(Y)+1); //high pass 29 | %Z2(1:36,1:44) = Y(1:36,1:44)/8; //LL 30 | 31 | LogTreshold = 10; 32 | 33 | if isstr(img) 34 | img=imread(img); 35 | end; 36 | if numel(grlvls)>1 37 | mapa=grlvls; 38 | else 39 | mapa=gray(grlvls); 40 | end; 41 | % maximg=max(img(:)); 42 | % minimg=min(img(:)); 43 | % if (maximg ~= minimg) 44 | % if maximg>255 | minimg<0 45 | % if log2(maximg-minimg)>LogTreshold 46 | % logimg=log2(abs(img)+1); 47 | % img=255*logimg/max(max(logimg)); 48 | % else 49 | % img=round(255*(img-minimg)./(maximg-minimg)); 50 | % end; 51 | % end; 52 | % if nargin<4 53 | % title='' 54 | % if nargin <3 55 | % scale=1; 56 | % end; 57 | % end; 58 | % end; 59 | 60 | set(0,'Units','pixels'); 61 | rd=get(0,'ScreenSize'); 62 | [rws,cls,ndms]=size(img); 63 | rws=scale*rws; 64 | cls=scale*cls; 65 | fwd=round(cls+cls*0.1); 66 | fhg=round(rws+rws*0.1); 67 | if ~isempty(strmatch('save_',title)) 68 | if ndims(img)==3 69 | imwrite(img,title); 70 | else 71 | imwrite(img,mapa,title); 72 | end; 73 | else 74 | figure('Name',title,'Menubar','none','Units','pixels','Position',[(rd(3)-fwd)/2 (rd(4)-fhg)/2 fwd fhg]); 75 | image(img); 76 | if ndims(img)<3 77 | colormap(mapa); 78 | end; 79 | fh=gca; 80 | set(gca,'DataAspectRatio',[1 1 1],'TickLength',[0 0],'XTick',[],'YTick',[],'Units','pixels','Position',[cls*0.05 rws*0.05 cls rws]); 81 | end; 82 | X=img; -------------------------------------------------------------------------------- /QualityAssessment/iq_measures.m: -------------------------------------------------------------------------------- 1 | function [MSE,PSNR,AD,SC,NK,MD,LMSE,NAE]=iq_measures(A,B,disp) 2 | %Image Quality Measures - various measures of reconstructed image quality 3 | %[MSE,PSNR,AD,SC,NK,MD,LMSE,NAE] = iq_measures(A,B,disp) 4 | % 5 | %Input: 6 | % A - array containing the original image or its filename 7 | % B - array containing the compressed image or its filename 8 | % disp - [optional, default = do not display] specifies whether the results 9 | % are displayed 10 | % if (disp == 'disp') all results are displayed on a command prompt 11 | % if (disp ~= 'disp') results are not displayed 12 | % 13 | %Note: 14 | % Number of specified outputs specifies what is actually computed. 15 | % if (nargout == 2) only MSE and PSNR are computed 16 | % if (nargout == 3) MSE, PSNR and AD are computed 17 | % ... 18 | % if (nargout == 8) all measures are computed 19 | % 20 | %Output: 21 | % MSE - Mean Squared Error 22 | % PSNR - Peak Signal to Noise Ratio 23 | % AD - Average Difference 24 | % SC - Structural Content 25 | % NK - Normalized Cross-Correlation 26 | % MD - Maximum Difference 27 | % LMSE - Laplacian Mean Squared Error 28 | % NAE - Normalized Absolute Error 29 | % 30 | %Example: 31 | % [MSE,PSNR]=iq_measures(A,B); 32 | % [MSE,PSNR,AD,SC,NK,MD,LMSE,NAE]=iq_measures('Lena1.png','Lena2.png'); 33 | % [MSE,PSNR]=iq_measures(A,'Lena2.png','disp'); 34 | 35 | if nargin<3 36 | disp=0; 37 | else 38 | disp = strcmp(disp,'disp'); 39 | end; 40 | if ischar(A) 41 | A=imread(A); 42 | end; 43 | if ischar(B) 44 | B=imread(B); 45 | end; 46 | if ~isa(A,'double') 47 | A=double(A); 48 | end; 49 | if ~isa(B,'double') 50 | B=double(B); 51 | end; 52 | 53 | numout = nargout; 54 | 55 | clrcomp = size(A,3); 56 | MSE = zeros(1,clrcomp); 57 | PSNR = zeros(1,clrcomp); 58 | AD = zeros(1,clrcomp); 59 | SC = zeros(1,clrcomp); 60 | NK = zeros(1,clrcomp); 61 | MD = zeros(1,clrcomp); 62 | LMSE = zeros(1,clrcomp); 63 | NAE = zeros(1,clrcomp); 64 | for i=1:size(A,3) 65 | if (disp && (clrcomp > 1)) fprintf('Component %d\n',i);end; 66 | [MSE(i),PSNR(i),AD(i),SC(i),NK(i),MD(i),LMSE(i),NAE(i)]=measureQ(A(:,:,i),B(:,:,i),disp,numout); 67 | end; 68 | 69 | function [MSE,PSNR,AD,SC,NK,MD,LMSE,NAE]=measureQ(A,B,disp,numout) 70 | PSNR=0; 71 | AD=0; 72 | SC=0; 73 | NK=0; 74 | MD=0; 75 | LMSE=0; 76 | NAE=0; 77 | 78 | R=A-B; 79 | Pk=sum(sum(A.^2)); 80 | 81 | % MSE 82 | MSE=sum(sum(R.^2))/(size(A,1)*size(A,2)); % MSE 83 | if (disp~=0) fprintf('MSE (Mean Squared Error) = %f\n',MSE);end; 84 | 85 | if (numout > 1) 86 | % PSNR 87 | if MSE>0 88 | PSNR=10*log10(255^2/MSE); 89 | else 90 | PSNR=Inf; 91 | end; 92 | if (disp~=0) fprintf('PSNR (Peak Signal / Noise Ratio) = %f dB\n',PSNR);end; 93 | end; 94 | 95 | if (numout > 2) 96 | % AD 97 | AD=sum(sum(R))/(size(A,1)*size(A,2)); % AD 98 | if disp~=0 fprintf('AD (Average Difference) = %f\n',AD);end; 99 | end; 100 | 101 | if (numout > 3) 102 | % SC 103 | Bs = sum(sum(B.^2)); 104 | if (Bs == 0) 105 | SC = Inf; 106 | else 107 | SC=Pk/sum(sum(B.^2)); 108 | end; 109 | if disp~=0 fprintf('SC (Structural Content) = %f\n',SC);end; 110 | end; 111 | 112 | if (numout > 4) 113 | % NK 114 | NK=sum(sum(A.*B))/Pk; 115 | if disp~=0 fprintf('NK (Normalised Cross-Correlation) = %f\n',NK);end; 116 | end; 117 | 118 | if (numout > 5) 119 | % MD 120 | MD=max(max(abs(R))); % MD 121 | if disp~=0 fprintf('MD (Maximum Difference) = %f\n',MD);end; 122 | end; 123 | 124 | if (numout > 6) 125 | % LMSE 126 | OP=4*del2(A); 127 | LMSE=sum(sum((OP-4*del2(B)).^2))/sum(sum(OP.^2)); 128 | if disp~=0 fprintf('LMSE (Laplacian Mean Squared Error) = %f\n',LMSE);end; 129 | end; 130 | 131 | if (numout > 7) 132 | % NAE 133 | NAE=sum(sum(abs(R)))/sum(sum(abs(A))); 134 | if disp~=0 fprintf('NAE (Normalised Absolute Error) = %f\n',NAE);end; 135 | end; 136 | -------------------------------------------------------------------------------- /Wavelet/2Dwavelet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/2Dwavelet.png -------------------------------------------------------------------------------- /Wavelet/CDF_9x7_scaling_analysis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/CDF_9x7_scaling_analysis.png -------------------------------------------------------------------------------- /Wavelet/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Nikola Sprljan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Wavelet/LeGall_5x3_h0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/LeGall_5x3_h0.png -------------------------------------------------------------------------------- /Wavelet/Lena_transform_coefficients.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/Lena_transform_coefficients.jpg -------------------------------------------------------------------------------- /Wavelet/Wavelets/Burt_5x7.wvf: -------------------------------------------------------------------------------- 1 | %Burt-Adelson 5x7 wavelet 2 | % 3 | % H = (170/280*x(0) - 73/280*(x(1)+x(-1)) - 15/280*(x(2)+x(-2)) + 3/280*(x(3)+x(-3))) * sqrt(2) 4 | % L = (3/5*x(0) + 1/4*(x(1)+x(-1)) - 1/20*(x(2)+x(-2))) * sqrt(2) 5 | 6 | %wvf_type 7 | SYMMETRIC_ODD 8 | %lift_coeff 9 | -0.2,-0.2 10 | 0.35714285714287,0.35714285714287 11 | -0.21,-0.21 12 | %lift_norm 13 | 0.98994949366113 14 | 1.01015254455224 15 | %filt_H0 - symmetric 16 | -2,-0.07071067811865 17 | -1, 0.35355339059327 18 | 0, 0.84852813742386 19 | 1, 0.35355339059327 20 | 2,-0.07071067811865 21 | %filt_H1 - symmetric 22 | -2, 0.01515228816828 23 | -1,-0.07576144084142 24 | 0,-0.36870567876156 25 | 1, 0.85862966286938 26 | 2,-0.36870567876156 27 | 3,-0.07576144084142 28 | 4, 0.01515228816828 29 | %filt_G0 - can be deduced from filt_H1 30 | %filt_G1 - can be deduced from filt_H0 31 | -------------------------------------------------------------------------------- /Wavelet/Wavelets/CDF_9x7.wvf: -------------------------------------------------------------------------------- 1 | %CDF_9x7 (Cohen-Daubechies-Feauveau wavelet) 2 | % 3 | %This biorthogonal wavelet filter bank is designed as a spline 4 | % variant with less dissimilar lengths. Originally published by 5 | % Cohen et al., this filter bank has seen widespread use in 6 | % image-processing applications. Initially used by Antonini, et al. 7 | % 8 | %Different variants appear, with different signs and/or scaling, the 9 | % most common one is where the low-pass filter coefficients are divided 10 | % by sqrt(2) while the high-pass are multiplied by the same factor. The 11 | % one provided here ensures that DC and Nyquist gain are sqrt(2). 12 | % Be aware of that when comparing to other sources! 13 | % 14 | %References: 15 | % 16 | %A. Cohen, I. Daubechies, J. C. Feauveau, 17 | % "Biorthogonal Bases of Compactly Supported Wavelets", 18 | % Communications on Pure and Applied Mathematics, vol. 45, no. 5, pp. 485-560, May 1992. 19 | % 20 | %M. Antonini, M. Barlaud, P. Mathieu, I. Daubechies, 21 | % "Image Coding Using Wavelet Transform", 22 | % IEEE Transactions on Image Processing, vol. 1, no. 2, pp. 205-220, April 1992. 23 | 24 | %wvf_type 25 | SYMMETRIC_ODD 26 | %lift_coeff 27 | -1.586134342,-1.586134342 28 | -0.052980118,-0.052980118 29 | 0.882911075, 0.882911075 30 | 0.443506852, 0.443506852 31 | %lift_norm 32 | 1.149604398 33 | 0.869864452 34 | %filt_H0 - symmetric 35 | -4, 0.03782845550726 36 | -3,-0.02384946501956 37 | -2,-0.11062440441844 38 | -1, 0.37740285561283 39 | 0, 0.85269867900889 40 | 1, 0.37740285561283 41 | 2,-0.11062440441844 42 | 3,-0.02384946501956 43 | 4, 0.03782845550726 44 | %filt_H1 - symmetric 45 | -2, 0.06453888262870 46 | -1,-0.04068941760916 47 | 0,-0.41809227322162 48 | 1, 0.78848561640558 49 | 2,-0.41809227322162 50 | 3,-0.04068941760916 51 | 4, 0.06453888262870 52 | %filt_G0 - can be deduced from filt_H1 53 | %filt_G1 - can be deduced from filt_H0 -------------------------------------------------------------------------------- /Wavelet/Wavelets/Haar.wvf: -------------------------------------------------------------------------------- 1 | % Haar wavelet 2 | % 3 | % H = (y - x) * (1 / sqrt(2)) 4 | % L = (x + y) * (1 / sqrt(2)) 5 | % 6 | % Prediction -> y' = y - x 7 | % Update -> x' = x + 0.5 * y' = (x + y)/2 8 | % Normalisation -> H = y' * (1 / sqrt(2)) 9 | % L = x' * sqrt(2) = sqrt(2) * x + H 10 | % 11 | % |1 -1| |1 0||sqrt(2) 0| 12 | % | | | || | 13 | % |0 1| |0.5 1||0 1/sqrt(2)| 14 | 15 | %wvf_type 16 | SYMMETRIC_EVEN 17 | %lift_coeff 18 | -1.0,0.0 19 | 0.0,0.5 20 | %lift_norm 21 | 1.41421356237310 22 | 0.70710678118655 23 | %filt_H0 - symmetric 24 | 0, 0.70710678118655 25 | 1, 0.70710678118655 26 | %filt_H1 - antisymmetric 27 | 0,-0.70710678118655 28 | 1, 0.70710678118655 29 | %filt_G0 - can be deduced from filt_H1 30 | %filt_G1 - can be deduced from filt_H0 31 | 32 | %Output of wavelet_check function 33 | % >> wavelet_check('Haar',3); 34 | % Analysis (decomposition) filters (H0 taps, H1 taps) = (2,2) 35 | % H0 taps = [0.70711 0.70711] 36 | % H1 taps = [-0.70711 0.70711] 37 | % H0 (DC,Nyquist) gain = (1.414214,0.000000) 38 | % H1 (DC,Nyquist) gain = (0.000000,1.414214) 39 | % 40 | % Synthesis (reconstruction) filters (H0 taps, H1 taps) = (2,2) 41 | % H0 taps = [0.70711 0.70711] 42 | % H1 taps = [0.70711 -0.70711] 43 | % H0 (DC,Nyquist) gain = (1.414214,0.000000) 44 | % H1 (DC,Nyquist) gain = (0.000000,1.414214) 45 | % 46 | % Orthogonality (test) = orthogonal (o) 47 | % H0/H1 L2 norms ratio = 1.000000 48 | % o/e reconstructed error energies ratio, (e,o) lattice = 1.000000 49 | % (e,e) lattice = 1.000000 50 | % Orthonormality parameter = -0.000000 51 | % Vanishing moments (test) = (1,1) 52 | % Time-frequency localisation wavelet f. (t, w) = 1.149999 (0.500000, 2.299998) 53 | % Time-frequency localisation scaling f. (t, w) = 0.567901 (0.500000, 1.135802) 54 | % 55 | % level L2(G0) L2(G1) dBIBO(L) dBIBO(H) PCR(e,o) 56 | % 1 1.00000 1.00000 1.41421 1.41421 1.00000 ( 1.00 1.00 ) 57 | % 2 1.00000 1.00000 1.41421 1.41421 1.00000 ( 1.00 1.00 1.00 1.00 ) 58 | % 3 1.00000 1.00000 1.41421 1.41421 1.00000 ( 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 ) 59 | % 60 | % Mean energy of difference (lifting - convolution), low-pass = 0.000000, high-pass = 0.000000 61 | % Mean energy of difference to original, lifting = 0.000000, convolution = 0.000000 -------------------------------------------------------------------------------- /Wavelet/Wavelets/Haar_deltalp.wvf: -------------------------------------------------------------------------------- 1 | % Haar wavelet with the update step disabled 2 | % 3 | % H = (y - x) * (1 / sqrt(2)) 4 | % L = x * sqrt(2) 5 | % 6 | % Prediction -> y' = y - x 7 | % Normalisation -> H = y' * (1 / sqrt(2)) 8 | % L = x' * sqrt(2) = x * sqrt(2) 9 | 10 | %wvf_type 11 | SYMMETRIC_ODD 12 | %lift_coeff 13 | -1.0,0.0 14 | %lift_norm 15 | 1.41421356237310 16 | 0.70710678118655 17 | %filt_H0 - no filtering performed, just normalisation 18 | 0, 1.41421356237310 19 | %filt_H1 - antisymmetric 20 | 0,-0.70710678118655 21 | 1, 0.70710678118655 22 | %filt_G0 - can be deduced from filt_H1 23 | %filt_G1 - can be deduced from filt_H0 24 | -------------------------------------------------------------------------------- /Wavelet/Wavelets/LeGall_5x3.wvf: -------------------------------------------------------------------------------- 1 | %LeGall_5x3 2 | % 3 | % H = (-1/2*x(-1) + x(0) - 1/2*x(1)) * (1 / sqrt(2)) 4 | % L = (-1/8*x(-2) + 1/4*x(-1) + 3/4*x(0) + 1/4*x(1) - 1/8*x(2)) * sqrt(2) 5 | % 6 | % Prediction -> y(0)' = y(0) - 0.5 * (x(-1) + x(1)) 7 | % Update -> x(0)' = x(0) + 0.25 * (y(-1)' + y(1)') 8 | % Normalisation -> H = y' * (1 / sqrt(2)) 9 | % L = x' * sqrt(2) 10 | 11 | %wvf_type 12 | SYMMETRIC_ODD 13 | %lift_coeff 14 | -0.5,-0.5 15 | 0.25,0.25 16 | %lift_norm 17 | 1.41421356237310 18 | 0.70710678118655 19 | %filt_H0 - symmetric 20 | -2,-0.17677669529664 21 | -1, 0.35355339059327 22 | 0, 1.06066017177982 23 | 1, 0.35355339059327 24 | 2,-0.17677669529664 25 | %filt_H1 - symmetric 26 | 0,-0.35355339059327 27 | 1, 0.70710678118655 28 | 2,-0.35355339059327 29 | %filt_G0 - can be deduced from filt_H1 30 | %filt_G1 - can be deduced from filt_H0 -------------------------------------------------------------------------------- /Wavelet/Wavelets/LeGall_5x3_deltalp.wvf: -------------------------------------------------------------------------------- 1 | %LeGall_5x3 with delta low-pass = 1/3 wavelet 2 | % 3 | % H = (-1/2*x(-1) + x(0) - 1/2*x(1)) * (1 / sqrt(2)) 4 | % L = x(0) * sqrt(2) 5 | % 6 | % Prediction -> y(0)' = y(0) - 0.5 * (x(-1) + x(1)) 7 | % Update -> x(0)' = x(0) 8 | % Normalisation -> H = y' * (1 / sqrt(2)) 9 | % L = x' * sqrt(2) 10 | 11 | %wvf_type 12 | SYMMETRIC_ODD 13 | %lift_coeff 14 | -0.5,-0.5 15 | %lift_norm 16 | 1.41421356237310 17 | 0.70710678118655 18 | %filt_H0 - - no filtering performed, just normalisation 19 | 0, 1.41421356237310 20 | %filt_H1 - symmetric 21 | 0,-0.35355339059327 22 | 1, 0.70710678118655 23 | 2,-0.35355339059327 24 | %filt_G0 - can be deduced from filt_H1 25 | %filt_G1 - can be deduced from filt_H0 26 | 27 | -------------------------------------------------------------------------------- /Wavelet/bibo_gains.m: -------------------------------------------------------------------------------- 1 | function [bgl,bgh,bglcum,bghcum]=bibo_gains(wavelet,n) 2 | %Computes BIBO(Bounded Input Bounded Output) gains of a wavelet 3 | %[bgl,bgh,bglcum,bghcum]=bibo_gains(wavelet,n) 4 | % 5 | %Input: 6 | % wavelet - wavelet identification string 7 | % n - number of maximum decomposition levels for which gain will be computed 8 | % 9 | %Output: 10 | % bgl - vector of BIBO gains for low-pass filter 11 | % bgh - vector of BIBO gains for high-pass filter 12 | % bglcum - vector of cumulative BIBO gains for low-pass filter 13 | % bghcum - vector of cumulative BIBO gains for high-pass filter 14 | % 15 | %Note: 16 | % The function displays result if there are no output arguments specified. 17 | % 18 | %Uses: 19 | % scaling_fun.m 20 | % wavelet_fun.m 21 | % 22 | %Example: 23 | % [bgl,bgh,bglcum,bghcum]=bibo_gains('CDF_9x7',15); 24 | 25 | if (nargout > 0) %display only if output is not defined 26 | disp = 0; 27 | else 28 | disp = 1; 29 | end; 30 | bgl = zeros(n,1); 31 | bgh = zeros(n,1); 32 | bglcum = zeros(n,1); 33 | bghcum = zeros(n,1); 34 | for i=0:n-1 35 | lp = scaling_fun(wavelet,i,'d'); 36 | bgl(i+1) = sum(abs(lp)); 37 | if (i > 0) 38 | bglcum(i + 1) = bgl(i + 1) / bgl(i); 39 | else 40 | bglcum(1) = bgl(1); 41 | end; 42 | hp = wavelet_fun(wavelet,i,'d'); 43 | bgh(i+1) = sum(abs(hp)); 44 | if (i > 0) 45 | bghcum(i + 1) = bgh(i + 1) / bgh(i); 46 | else 47 | bghcum(1) = bgh(1); 48 | end; 49 | end; 50 | if disp 51 | fprintf('Low-pass filter (H0) BIBO gains (cumulative)= '); 52 | for i=1:n 53 | fprintf('%.2f(%.2f) ',bgl(i),bglcum(i)); 54 | end; 55 | fprintf('\nHigh-pass filter (H1) BIBO gains (cumulative)= '); 56 | for i=1:n 57 | fprintf('%.2f(%.2f) ',bgh(i),bghcum(i)); 58 | end; 59 | fprintf('\n'); 60 | end; 61 | 62 | -------------------------------------------------------------------------------- /Wavelet/draw_packets.m: -------------------------------------------------------------------------------- 1 | function draw_packets(D,N,pdep,s,packet_stream) 2 | %Visualises the wavelet packets decomposition 3 | %draw_packets(D,N,pdep,s,packet_stream) 4 | % 5 | %Input: 6 | % D - array of wavelet coefficients 7 | % N - number of dyadic (pre-packet) decompositions 8 | % pdep - "packet decomposition depth" 9 | % s - structure containing info on parent-children relationship between subbands 10 | % (see in decomp_packets.m) 11 | % packet_stream - stream of bits representing information on splitting decisions 12 | % of wavelet packets decomposition 13 | % 14 | %Note: 15 | % Draws 4 plots. 16 | % 17 | %Example: 18 | % par=struct('N',5,'pdep',2,'wvf',load_wavelet('CDF_9x7'),'dec','greedy'); 19 | % ent_par=struct('ent','shannon','opt',0); 20 | % [D,packet_stream,s,E]=decomp_packets2D('lena256.png',par,ent_par); 21 | % draw_packets(D,par.N,par.pdep,s,packet_stream); 22 | 23 | scrsz = get(0,'ScreenSize'); 24 | figure('Name','Wavelet packet structure drawn by bit information'); 25 | pdep=pdep-N+1; 26 | if size(packet_stream,2)>1 27 | packet_stream=fliplr(packet_stream); 28 | end; 29 | cnt=0; 30 | set(gca,'YDir','reverse','PlotBoxAspectRatio',[1 1 1],'XTick',[],'YTick',[]); 31 | siz=1/(2^N); 32 | for i=1:N 33 | rectangle('Position',[0,0,siz,siz]); 34 | rectangle('Position',[0,siz,siz,siz]); 35 | rectangle('Position',[siz,0,siz,siz]); 36 | rectangle('Position',[siz,siz,siz,siz]); 37 | if pdep>0 38 | cnt=draw_subband(siz,siz,packet_stream,cnt,siz,pdep); 39 | cnt=draw_subband(0,siz,packet_stream,cnt,siz,pdep); 40 | cnt=draw_subband(siz,0,packet_stream,cnt,siz,pdep); 41 | end; 42 | siz=siz*2; 43 | pdep=pdep+1; 44 | end; 45 | %second plot - drawn by subband structure s (small - convinient for copy/paste) 46 | figure('Position',[300 200 200 200],'Name','Wavelet packet structure drawn by ''s'' subband structure'); 47 | set(gca,'YDir','reverse','PlotBoxAspectRatio',[1 1 1],'XTick',[],'YTick',[],'Position',[0.005 0.005 0.99 0.99]); 48 | axis([0 size(D,2) 0 size(D,1)]); 49 | wavelet_dec_bands=N*3+1; 50 | for i=1:size(s,2) 51 | if i<=wavelet_dec_bands 52 | lw=2; 53 | else 54 | lw=1; 55 | end; 56 | rectangle('Position',s(i).band_abs,'LineWidth',lw); 57 | end; 58 | %third plot - drawn by subband structure s, with linked subbands 59 | %figure('Position',[1 scrsz(4)/2 scrsz(3)/2 scrsz(4)/2]) 60 | figure('Position',[scrsz(3)/2-3*scrsz(4)/8 scrsz(4)/2-3*scrsz(4)/8 6*scrsz(4)/8 6*scrsz(4)/8],... 61 | 'Name','Wavelet packet structure drawn by s - subabnd structure'); 62 | set(gca,'YDir','reverse','PlotBoxAspectRatio',[1 1 1],'XTick',[],'YTick',[],'Position',[0.005 0.005 0.99 0.99]); 63 | axis([0 size(D,2) 0 size(D,1)]); 64 | wavelet_dec_bands=N*3+1; 65 | for i=1:size(s,2) 66 | if i<=wavelet_dec_bands 67 | lw=2; 68 | else 69 | lw=1; 70 | end; 71 | rectangle('Position',s(i).band_abs,'LineWidth',lw); 72 | end; 73 | cmap=colormap('prism'); 74 | lv=1; 75 | link_subbands(s(1),s,cmap,lv); 76 | %and finally draw decomposed subbands 77 | figure('Name','Wavelet packet transform coefficients'); 78 | set(gca,'YDir','reverse','PlotBoxAspectRatio',[1 1 1],'XTick',[],'YTick',[]); 79 | axis([0 size(D,2) 0 size(D,1)]); 80 | image('CData',100*log10(abs(D)));colormap(gray(256)); 81 | for i=1:size(s,2) 82 | if i<=wavelet_dec_bands 83 | lw=2; 84 | else 85 | lw=1; 86 | end; 87 | rectangle('Position',s(i).band_abs,'LineWidth',lw,'EdgeColor','white'); 88 | end; 89 | 90 | function cnt=draw_subband(sx,sy,packet_stream,cnt,siz,pdep) 91 | cnt=cnt+1; 92 | if packet_stream(cnt) 93 | pdep=pdep-1; 94 | siz=siz/2; 95 | rectangle('Position',[sx,sy,siz,siz]); 96 | rectangle('Position',[sx+siz,sy,siz,siz]); 97 | rectangle('Position',[sx,sy+siz,siz,siz]); 98 | rectangle('Position',[sx+siz,sy+siz,siz,siz]); 99 | if pdep>0 100 | cnt=draw_subband(sx+siz,sy+siz,packet_stream,cnt,siz,pdep); 101 | cnt=draw_subband(sx,sy+siz,packet_stream,cnt,siz,pdep); 102 | cnt=draw_subband(sx+siz,sy,packet_stream,cnt,siz,pdep); 103 | cnt=draw_subband(sx,sy,packet_stream,cnt,siz,pdep); 104 | end; 105 | %siz=siz*2; 106 | end; 107 | 108 | function link_subbands(node,s,cmap,lv) 109 | n=node.children; 110 | if n(1)>0 111 | for i=1:size(n,2) 112 | child=s(n(i)); 113 | link_subbands(child,s,cmap,lv+1); 114 | %krc0=floor(lv/2)/lv; 115 | %krc1=floor((lv+1)/2)/(lv+1); 116 | childcoordx=child.band_abs(1)+child.band_abs(3)/4; 117 | childcoordy=child.band_abs(2)+child.band_abs(4)/4; 118 | parentcoordx=node.band_abs(1)+node.band_abs(3)/2; 119 | parentcoordy=node.band_abs(2)+node.band_abs(4)/2; 120 | line([parentcoordx childcoordx],[parentcoordy childcoordy],'Color',cmap(lv,:)); 121 | text(childcoordx,childcoordy,int2str(n(i))); 122 | %next line for use with arrow.m by F. Golnaraghi et al. 123 | %arrow([parentcoordx parentcoordy],[childcoordx childcoordy],'Length',10); 124 | end; 125 | end; -------------------------------------------------------------------------------- /Wavelet/dwt_2D.m: -------------------------------------------------------------------------------- 1 | function [A,H,V,D]=dwt_2D(X,wavelet) 2 | %Two-dimensional separable DWT 3 | %[A,H,V,D]=dwt_2D(X,wavelet) 4 | % 5 | %Input: 6 | % X - matrix to be transformed containing the input signal 7 | % wavelet - wavelet identification string, or wavelet data structure 8 | % 9 | %Output: 10 | % A,H,V,D - approximation signal, horizontal, vertical and diagonal details 11 | % signal 12 | % 13 | %Uses: 14 | % load_wavelet.m 15 | % dwt_dim.m 16 | % subband.m 17 | % 18 | %Example: 19 | % [A,H,V,D] = dwt_2D(X,'CDF_9x7'); 20 | 21 | %load the wavelet here 22 | if ischar(wavelet) 23 | wvf = load_wavelet(wavelet); 24 | else 25 | wvf = wavelet; 26 | end; 27 | 28 | X = dwt_dim(X,1,wvf); %columns 29 | X = dwt_dim(X,2,wvf); %rows 30 | 31 | A = subband(X,1,'ll'); 32 | H = subband(X,1,'hl'); 33 | V = subband(X,1,'lh'); 34 | D = subband(X,1,'hh'); 35 | -------------------------------------------------------------------------------- /Wavelet/dwt_conv1D.m: -------------------------------------------------------------------------------- 1 | function [a,d] = dwt_conv1D(x,wvf) 2 | %DWT of a 1D signal in convolution implementation 3 | %[a,d]=dwt_conv1D(x,wvf) 4 | % 5 | %Input: 6 | % x - signal to be transformed 7 | % wvf - wavelet identification string, or wavelet data structure 8 | % 9 | %Output: 10 | % a - approximation (low-pass) signal 11 | % d - detail (high-pass) signal 12 | % 13 | %Note: 14 | % TODO: handle the situation where the signal is shorter than what the 15 | % extension requires. Different extensions. 16 | % 17 | %Uses: 18 | % load_wavelet.m 19 | % 20 | %Example: 21 | % [a,d] = dwt_conv1D(x,wvf); 22 | % [a,d] = dwt_conv1D(x,'CDF_9x7'); 23 | 24 | if ischar(wvf) 25 | wvf = load_wavelet(wvf); 26 | end; 27 | sym_ext = false; 28 | if (strcmp(wvf.wvf_type,'symmetric_even') || strcmp(wvf.wvf_type,'symmetric_odd')) 29 | sym_ext = true; 30 | end; 31 | 32 | %low-pass filtering 33 | Lle = -1 * wvf.filt_H0_delay(1); %left extension length 34 | Lre = wvf.filt_H0_delay(end); %right extension length 35 | if (sym_ext) 36 | %setup the indices by using the symmetric extension 37 | I = [(Lle+1):-1:2 1:length(x) (length(x)-1):-1:(length(x) - Lre)]; 38 | else 39 | %setup the indices by using the periodic extension 40 | I = [(length(x) - Lle):(length(x)-1) 1:length(x) 1:Lre]; 41 | end; 42 | h0 = fliplr(wvf.filt_H0); 43 | %oversampled approximation signal 44 | ao = conv2(x(I),h0,'valid'); 45 | %downsample 46 | a = ao(1:2:end); 47 | 48 | %high-pass filtering 49 | Hle = -1 * wvf.filt_H1_delay(1); %left extension 50 | Hre = wvf.filt_H1_delay(end); %right extension 51 | if (sym_ext) 52 | %setup the indices by using the symmetric extension 53 | I = [(Hle+1):-1:2 1:length(x) (length(x)-1):-1:(length(x) - Hre)]; 54 | else 55 | %setup the indices by using the periodic extension 56 | I = [(length(x) - Hle):(length(x)-1) 1:length(x) 1:Hre]; 57 | end; 58 | h1 = fliplr(wvf.filt_H1); 59 | %oversampled approximation signal 60 | do = conv2(x(I),h1,'valid'); 61 | %downsample 62 | d = do(1:2:end); 63 | -------------------------------------------------------------------------------- /Wavelet/dwt_dim.m: -------------------------------------------------------------------------------- 1 | function X=dwt_dim(X,d,wavelet) 2 | %DWT in specific dimension of an n-dimensional matrix 3 | %X=dwt_dim(X,d,wavelet) 4 | % 5 | %Input: 6 | % X - matrix to be transformed containing the input signal 7 | % d - dimension in which the transform will take place 8 | % wavelet - wavelet identification string, or wavelet data structure 9 | % 10 | %Output: 11 | % X - matrix of wavelet coefficients 12 | % 13 | %Note: 14 | % Filters across the d-th dimension. For instance, if X is 2D then it first 15 | % filters across columns, as size(X,1) is number of rows (column length). 16 | % 17 | %Uses: 18 | % load_wavelet.m 19 | % dwt_lifting1D.m 20 | % subband_dim.m 21 | % 22 | %Example: 23 | % Y = dwt_dim(X,1,'CDF_9x7'); 24 | 25 | %load the wavelet here 26 | if ischar(wavelet) 27 | wvf = load_wavelet(wavelet); 28 | else 29 | wvf = wavelet; 30 | end; 31 | 32 | if ~isa(X,'double') 33 | X = double(X); 34 | end; 35 | N = ndims(X); 36 | dimprod = numel(X); 37 | X = shiftdim(X,d-1); %rotates the order of dimensions 38 | sv = size(X); %matrix size before reshaping 39 | sizdim = sv(1); %size of the first dimension 40 | if sizdim > 1 %if non-singleton dimension 41 | sizcol = dimprod/sizdim; %product of other dimensions 42 | X = reshape(X,sizdim,sizcol); %reshape into 2D sizdim x sizcol matrix 43 | lpasiz = subband_dim(sizdim, 1); 44 | for j=1:sizcol 45 | [X(1:lpasiz,j),X(lpasiz+1:sizdim,j)] = dwt_lifting1D(X(:,j),wvf); 46 | end; 47 | X = reshape(X,sv); 48 | end; 49 | X = shiftdim(X,N-d+1); %rotates the order of dimensions forward to the original -------------------------------------------------------------------------------- /Wavelet/dwt_dyadic_decomp.m: -------------------------------------------------------------------------------- 1 | function [Y,N]=dwt_dyadic_decomp(X,wavelet,N) 2 | %Dyadic wavelet decomposition of a multidimensional signal 3 | %[Y,N]=dwt_dyadic_decomp(X,wavelet,N) 4 | % 5 | %Input: 6 | % X - matrix to be transformed containing the input signal or image's 7 | % filename (in that case the transform is 2D) 8 | % wavelet - wavelet identification string 9 | % N - [optional, default = max] specifies the number of levels of decomposition 10 | % default value is the maximum possible, e.g. down to the smallest possible 11 | % LL subband 12 | % 13 | %Output: 14 | % Y - matrix of wavelet coefficients 15 | % N - number of actually performed levels of decomposition 16 | % 17 | %Note: 18 | % Performs dyadic decomposition, i.e. the dimensions of low-pass subband 19 | % are half of the original subband. 20 | % 21 | %Uses: 22 | % submatrix.m 23 | % dwt_dim.m 24 | % subband_dim.m 25 | % 26 | %Example: 27 | % Y=dwt_dyadic_decomp(X,'CDF_9x7',6); 28 | % [Y,N]=dwt_dyadic_decomp('Lena512.png','Haar'); 29 | 30 | if ischar(X) 31 | X=imread(X); 32 | end; 33 | Y=double(X); 34 | 35 | transposed = 0; %by default do not transpose 36 | if isvector(X) 37 | n = 1; %number of dimensions 38 | if (size(X,1) == 1) %if one-row vector, needs to be transposed 39 | Y = Y'; 40 | transposed = 1; %remember to transpose it back later 41 | end; 42 | else 43 | n = ndims(Y); 44 | end; 45 | Xsiz=size(Y); 46 | 47 | %to find Nmax - the maximum number of decompositions possible 48 | [ld,hd,Nmax]= subband_dim(Xsiz, Inf); 49 | if nargin==2 50 | %if not specified, the number of decomposition is set to Nmax 51 | N = Nmax; 52 | elseif (N > Nmax) 53 | warning(['Specified number of decompositions exceeds the maximum. N is set to Nmax = ' num2str(Nmax)]); 54 | N = Nmax; 55 | end; 56 | 57 | Lsiz = Xsiz; %low-pass subband dimensions 58 | for i=1:N 59 | [Li,Lind] = submatrix(Y,Lsiz); 60 | for j=1:n %transform in the j-th dimension 61 | Li = dwt_dim(Li,j,wavelet); 62 | end; 63 | Y(Lind{:}) = Li; 64 | Lsiz = ceil(Lsiz/2); %i.e. low-pass of signal of 3 samples contains 2 samples 65 | end; 66 | 67 | if transposed 68 | Y = Y'; 69 | end; 70 | -------------------------------------------------------------------------------- /Wavelet/dwt_lifting1D.m: -------------------------------------------------------------------------------- 1 | function [a,d] = dwt_lifting1D(x,wvf) 2 | %DWT of a 1D signal in lifting implementation 3 | %[a,d]=dwt_lifting1D(x,wvf) 4 | % 5 | %Input: 6 | % x - signal to be transformed 7 | % wvf - wavelet identification string, or wavelet data structure 8 | % 9 | %Output: 10 | % a - approximation (low-pass) signal 11 | % d - detail (high-pass) signal 12 | % 13 | %Uses: 14 | % load_wavelet.m 15 | % 16 | %Example: 17 | % [a,d] = dwt_lifting1D(x,wvf); 18 | % [a,d] = dwt_lifting1D(x,'CDF_9x7'); 19 | 20 | if ischar(wvf) 21 | wvf = load_wavelet(wvf); 22 | end; 23 | s = wvf.lift_coeff; 24 | K = wvf.lift_norm; 25 | cn = wvf.lift_cnct; 26 | 27 | %xe - for 1-pixel extended signal 28 | xe = zeros(1,length(x)+2); 29 | xe(2:end-1) = x; 30 | if (strcmp(cn,'00')) 31 | warning('Lifting not available!'); 32 | else 33 | for i=1:size(s,1) 34 | xe(1) = xe(3); %extension on the left 35 | xe(end) = xe(end-2); %extension on the right 36 | start = rem(i,2); %determines if it is prediction or update step, 1 - prediction, 0 - update 37 | lind = 1+start:2:length(xe)-2; 38 | cind = lind + 1; 39 | rind = cind + 1; 40 | if (cn(i,1) == '1') %left connection present 41 | xe(cind) = xe(cind) + s(i,1)*xe(lind); %left pixel lifting 42 | end; 43 | if (cn(i,2) == '1') %right connection present 44 | xe(cind) = xe(cind) + s(i,2)*xe(rind); %right pixel lifting 45 | end; 46 | end; 47 | end; 48 | %normalisation 49 | a = xe(2:2:end-1) * K(1); 50 | d = xe(3:2:end-1) * K(2); -------------------------------------------------------------------------------- /Wavelet/filt2lift.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/filt2lift.m -------------------------------------------------------------------------------- /Wavelet/idwt_2D.m: -------------------------------------------------------------------------------- 1 | function Y = idwt_2D(A,H,V,D,wavelet) 2 | %Two-dimensional separable IDWT 3 | %Y=idwt_2D(A,H,V,D,wavelet) 4 | % 5 | %Input: 6 | % A,H,V,D - approximation signal, horizontal, vertical and diagonal details 7 | % signal 8 | % wavelet - wavelet identification string, or wavelet data structure 9 | % 10 | %Output: 11 | % Y - reconstructed matrix 12 | % 13 | %Uses: 14 | % load_wavelet.m 15 | % idwt_dim.m 16 | % 17 | %Example: 18 | % Y = idwt_2D(A,H,V,D,'CDF_9x7'); 19 | 20 | %load the wavelet here 21 | if ischar(wavelet) 22 | wvf = load_wavelet(wavelet); 23 | else 24 | wvf = wavelet; 25 | end; 26 | Y = [A H;V D]; 27 | Y = idwt_dim(Y,2,wvf); %rows 28 | Y = idwt_dim(Y,1,wvf); %columns 29 | -------------------------------------------------------------------------------- /Wavelet/idwt_conv1D.m: -------------------------------------------------------------------------------- 1 | function y = idwt_conv1D(a,d,wvf) 2 | %IDWT of a 1D signal in convolution implementation 3 | %y=idwt_conv1D(a,d,wvf) 4 | % 5 | %Input: 6 | % a - approximation (low-pass) signal 7 | % d - detail (high-pass) signal 8 | % wvf - wavelet identification string, or wavelet data structure 9 | % 10 | %Output: 11 | % y - reconstructed signal 12 | % 13 | %Uses: 14 | % load_wavelet.m 15 | % 16 | %Note: 17 | % TODO: handle the situation where the signal is shorter than what the 18 | % extension requires. Different extensions. 19 | % 20 | %Example: 21 | % y = idwt_conv1D(a,d,wvf); 22 | % y = idwt_conv1D(a,d,'CDF_9x7'); 23 | 24 | if ischar(wvf) 25 | wvf = load_wavelet(wvf); 26 | end; 27 | sym_ext = false; 28 | if (strcmp(wvf.wvf_type,'symmetric_even') || strcmp(wvf.wvf_type,'symmetric_odd')) 29 | sym_ext = true; 30 | end; 31 | 32 | %%low-pass filtering%% 33 | Lle = -1 * wvf.filt_G0_delay(1); %left extension 34 | Lre = wvf.filt_G0_delay(end); %right extension 35 | %upsample the approximation signal 36 | au = zeros(1, 2*length(a)); 37 | au(1:2:end) = a; 38 | if (sym_ext) 39 | %setup the indices by using the symmetric extension 40 | I = [(Lle+1):-1:2 1:length(au) (length(au)-1):-1:(length(au) - Lre)]; 41 | else 42 | %setup the indices by using the periodic extension 43 | I = [(length(au) - Lle):(length(au)-1) 1:length(au) 1:Lre]; 44 | end; 45 | g0 = fliplr(wvf.filt_G0); 46 | %convolution 47 | ao = conv2(au(I),g0,'valid'); 48 | 49 | %%high-pass filtering%% 50 | Hle = -1 * wvf.filt_G1_delay(1); %left extension 51 | Hre = wvf.filt_G1_delay(end); %right extension 52 | %upsample the detail signal 53 | du = zeros(1, 2*length(d)); 54 | du(2:2:end) = d; %subsampling defined so it starts on odd pixels 55 | %Note that symmetric extension is here different since the point of 56 | %symmetry is around odd numbered pixel! 57 | if (sym_ext) 58 | %setup the indices by using the symmetric extension 59 | I = [(Hle+1):-1:2 1:length(du) (length(du)-1):-1:(length(du) - Hre)]; 60 | else 61 | %setup the indices by using the periodic extension 62 | I = [(length(du) - Hle):(length(du)-1) 1:length(du) 1:Hre]; 63 | end; 64 | g1 = fliplr(wvf.filt_G1); 65 | %convolution 66 | do = conv2(du(I),g1,'valid'); 67 | 68 | %%combine%% 69 | y = ao + do; 70 | -------------------------------------------------------------------------------- /Wavelet/idwt_dim.m: -------------------------------------------------------------------------------- 1 | function X = idwt_dim(X,d,wavelet) 2 | %IDWT in specific dimension of an n-dimensional matrix 3 | %X=idwt_dim(X,d,wavelet) 4 | % 5 | %Input: 6 | % X - matrix of wavelet coeffcients 7 | % d - dimension in which the transform will take place 8 | % wavelet - wavelet identification string, or wavelet data structure 9 | % 10 | %Output: 11 | % X - reconstructed matrix 12 | % 13 | %Uses: 14 | % load_wavelet.m 15 | % idwt_lifting1D.m 16 | % subband_dim.m 17 | % 18 | %Example: 19 | % X = idwt_dim(Y,1,'Haar'); 20 | 21 | %load the wavelet here 22 | if ischar(wavelet) 23 | wvf = load_wavelet(wavelet); 24 | else 25 | wvf = wavelet; 26 | end; 27 | 28 | N = ndims(X); 29 | dimprod = numel(X); 30 | X = shiftdim(X,d-1); %rotates the order of dimensions 31 | sv = size(X); %matrix size before reshaping 32 | sizdim = sv(1); %size of the first dimension 33 | if sizdim > 1 %if non-singleton dimension 34 | sizcol = dimprod/sizdim; %product of other dimensions 35 | X = reshape(X,sizdim,sizcol); %reshape into 2D sizdim x sizcol matrix 36 | [lpasiz,hpasiz] = subband_dim(sizdim, 1); 37 | for j=1:sizcol 38 | X(:,j) = idwt_lifting1D(X(1:lpasiz,j),X(lpasiz+1:sizdim,j),wvf); 39 | end; 40 | X = reshape(X,sv); 41 | end; 42 | X = shiftdim(X,N-d+1); %rotates the order of dimensions forward to the original -------------------------------------------------------------------------------- /Wavelet/idwt_dyadic_recon.m: -------------------------------------------------------------------------------- 1 | function Xr = idwt_dyadic_recon(Y,wavelet,N) 2 | %Dyadic wavelet reconstruction of a multidimensional signal 3 | %X=idwt_dyadic_recon(Y,wavelet,N) 4 | % 5 | %Input: 6 | % X - matrix of wavelet coefficients 7 | % wavelet - wavelet identification string 8 | % N - specifies the number of levels of reconstruction (inverse DWT) 9 | % 10 | %Output: 11 | % Xr - reconstructed matrix 12 | % 13 | %Uses: 14 | % submatrix.m 15 | % idwt_dim.m 16 | % 17 | %Example: 18 | % Xr=idwt_dyadic_recon(Y,'CDF_9x7',6); 19 | 20 | Xr=double(Y); 21 | 22 | transposed = 0; %by default, do not transpose 23 | if (size(Y,1) == 1) %if one-row vector, needs to be transposed 24 | Xr = Xr'; 25 | transposed = 1; %remember to transpose it back later 26 | end; 27 | Xsiz=size(Xr); 28 | if isvector(Xr) 29 | n = 1; 30 | else 31 | n = ndims(Xr); 32 | end; 33 | 34 | for i=N-1:-1:0 35 | Lsiz = ceil(Xsiz / 2^i); %low-pass subband dimensions 36 | [Li,Lind] = submatrix(Xr,Lsiz); 37 | for j=n:-1:1 %inverse transform in j-th dimension 38 | Li = idwt_dim(Li,j,wavelet); 39 | end; 40 | Xr(Lind{:}) = Li; 41 | end; 42 | 43 | if transposed 44 | Xr = Xr'; 45 | end; 46 | -------------------------------------------------------------------------------- /Wavelet/idwt_lifting1D.m: -------------------------------------------------------------------------------- 1 | function y = idwt_lifting1D(a,d,wvf) 2 | %IDWT of a 1D signal in lifting implementation 3 | %y=idwt_lifting1D(a,d,wvf) 4 | % 5 | %Input: 6 | % a - approximation (low-pass) signal 7 | % d - detail (high-pass) signal 8 | % wvf - wavelet identification string, or wavelet data structure 9 | % 10 | %Output: 11 | % y - reconstructed signal 12 | % 13 | %Uses: 14 | % load_wavelet.m 15 | % 16 | %Example: 17 | % y = idwt_lifting1D(a,d,wvf); 18 | % y = idwt_lifting1D(a,d,'CDF_9x7'); 19 | 20 | if ischar(wvf) 21 | wvf = load_wavelet(wvf); 22 | end; 23 | s = wvf.lift_coeff; 24 | K = wvf.lift_norm; 25 | cn = wvf.lift_cnct; 26 | 27 | %xe - for 1-pixel extended signal 28 | xe = zeros(1,length(a)+length(d)+2); 29 | %undo the normalisation 30 | xe(2:2:end-1) = a / K(1); 31 | xe(3:2:end-1) = d / K(2); 32 | if (strcmp(cn,'00')) 33 | warning('Lifting not available!'); 34 | else 35 | for i=size(s,1):-1:1 36 | xe(1) = xe(3); %extension on the left 37 | xe(end) = xe(end-2); %extension on the right 38 | start = rem(i,2); %determines if it is prediction or update step, 1 - prediction, 0 - update 39 | lind = 1+start:2:length(xe)-2; 40 | cind = lind + 1; 41 | rind = cind + 1; 42 | if (cn(i,1) == '1') %left connection present 43 | xe(cind) = xe(cind) - s(i,1)*xe(lind); %left pixel lifting 44 | end; 45 | if (cn(i,2) == '1') %right connection present 46 | xe(cind) = xe(cind) - s(i,2)*xe(rind); %right pixel lifting 47 | end; 48 | end; 49 | end; 50 | y = xe(2:end-1); 51 | 52 | -------------------------------------------------------------------------------- /Wavelet/load_wavelet.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/load_wavelet.m -------------------------------------------------------------------------------- /Wavelet/recon_packets2D.m: -------------------------------------------------------------------------------- 1 | function A=recon_packets2D(D,param,packet_stream) 2 | %2D wavelet packets reconstruction 3 | %A=recon_packets2D(D,param,packet_stream) 4 | % 5 | %Input: 6 | % D - array of wavelet coefficients 7 | % param - structure containing decomposition parameters (see in 8 | % decomp_packets.m) 9 | % packet_stream - stream of bits representing information on splitting decisions 10 | % of wavelet packets decomposition 11 | % 12 | %Output: 13 | % A - reconstructed array 14 | % 15 | %Uses: 16 | % idwt_2D.m 17 | % 18 | %Example: 19 | % [D,packet_stream]=decomp_packets2D(Y,par,ent_par);%see decomp_packets2D.m 20 | % A=recon_packets2D(D,par,packet_stream); 21 | 22 | param.pdep=param.pdep-param.N+1; %e.g. if N=5 and pdep=2 -> param.pdep=-2 23 | if size(packet_stream,2)>1 24 | packet_stream=fliplr(packet_stream); 25 | entropy=1; 26 | else 27 | entropy=0; 28 | end; 29 | cnt=0; 30 | siz=size(D)/(2^param.N); 31 | for i=1:param.N 32 | D1=D(1:siz(1),1:siz(2)); 33 | DH1=D(1:siz(1),siz(2)+1:2*siz(2)); 34 | DV1=D(siz(1)+1:2*siz(1),1:siz(2)); 35 | DD1=D(siz(1)+1:2*siz(1),siz(2)+1:2*siz(2)); 36 | if (i > 1) && (param.pdep > 0) && entropy 37 | [DD1,cnt]=recon_entropy(DD1,param,packet_stream,cnt); 38 | [DV1,cnt]=recon_entropy(DV1,param,packet_stream,cnt); 39 | [DH1,cnt]=recon_entropy(DH1,param,packet_stream,cnt); 40 | end; 41 | A=idwt_2D(D1,DH1,DV1,DD1,param.wvf); 42 | siz=siz*2; 43 | D(1:siz(1),1:siz(2))=A; 44 | param.pdep=param.pdep+1; 45 | end; 46 | 47 | function [band,cnt]=recon_entropy(band,param,packet_stream,cnt) 48 | cnt=cnt+1; 49 | if packet_stream(cnt) 50 | param.pdep=param.pdep-1; 51 | siz=size(band)/2; 52 | D1=band(1:siz(1),1:siz(2)); 53 | DH1=band(1:siz(1),siz(2)+1:2*siz(2)); 54 | DV1=band(siz(1)+1:2*siz(1),1:siz(2)); 55 | DD1=band(siz(1)+1:2*siz(1),siz(2)+1:2*siz(2)); 56 | if param.pdep>0 57 | [DD1,cnt]=recon_entropy(DD1,param,packet_stream,cnt); 58 | [DV1,cnt]=recon_entropy(DV1,param,packet_stream,cnt); 59 | [DH1,cnt]=recon_entropy(DH1,param,packet_stream,cnt); 60 | [D1,cnt]=recon_entropy(D1,param,packet_stream,cnt); 61 | end; 62 | band=idwt_2D(D1,DH1,DV1,DD1,param.wvf); 63 | end; -------------------------------------------------------------------------------- /Wavelet/scaling_fun.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/scaling_fun.m -------------------------------------------------------------------------------- /Wavelet/subband.m: -------------------------------------------------------------------------------- 1 | function [S,Sind,Sdim]=subband(D,N,band) 2 | %[S,Sind,Sdim]=subband(D,N,band) 3 | %Version: 3.01, Date: 2005/01/01, author: Nikola Sprljan 4 | % 5 | %Input: 6 | % D - array of wavelet coefficients 7 | % N - specifies the decomposition level 8 | % band - specifies the subband ('ll', 'hl', 'lh' or 'hh') 9 | % 10 | %Output: 11 | % S - array of the subband wavelet coefficients 12 | % Sind - indices of elements of the selected subband 13 | % Sdim - dimensions of the selected subband 14 | % 15 | %Note: 16 | % ('ll', 'hl', 'lh', 'hh') corresponds to ('a', 'h', 'v' ,'d') 17 | % 18 | %Uses: 19 | % subband_dim.m 20 | % 21 | %Example: 22 | % D=dwt_dyadic_decomp(A,'CDF_9x7',4); 23 | % S=subband(D,4,'hl'); 24 | % S=subband(D,6,'ll'); 25 | 26 | if (ndims(D) ~= 2) 27 | error('Wavelet coefficients array of other dimensions than 2D!'); 28 | end; 29 | 30 | [sizrow,sizcol] = size(D); 31 | [ldr,hdr]= subband_dim(sizrow, N); 32 | [ldc,hdc]= subband_dim(sizcol, N); 33 | Sind = []; 34 | switch band 35 | case 'll' 36 | Sind{1} = 1:ldr; 37 | Sind{2} = 1:ldc; 38 | Sdim = [ldr ldc]; 39 | case 'hl' 40 | Sind{1} = 1:ldr; 41 | Sind{2} = ldc+1:ldc+hdc; 42 | Sdim = [ldr hdc]; 43 | case 'lh' 44 | Sind{1} = ldr+1:ldr+hdr; 45 | Sind{2} = 1:ldc; 46 | Sdim = [hdr ldc]; 47 | case 'hh' 48 | Sind{1} = ldr+1:ldr+hdr; 49 | Sind{2} = ldc+1:ldc+hdc; 50 | Sdim = [hdr hdc]; 51 | end; 52 | S = D(Sind{:}); 53 | -------------------------------------------------------------------------------- /Wavelet/subband_dim.m: -------------------------------------------------------------------------------- 1 | function [ld,hd,N] = subband_dim(sdim, N) 2 | %Computes the subband dimensions for a specified number of decompositions 3 | %[ld,hd,N]=subband_dim(sdim, N) 4 | % 5 | %Input: 6 | % sdim - vector of lengths of the original signal 7 | % N - number of signal decompositions 8 | % 9 | %Output: 10 | % ld - size of the low-pass signal after N levels of decomposition 11 | % hd - size of the high-pass signal after N levels of decomposition 12 | % N - number of actually performed number of decompositions 13 | % 14 | %Note: 15 | % If N is too large, the function will return ld = 1, and N will equal 16 | % the number of allowed decompositions. 17 | % In the smallest non-singleton dimension direction the low-pass subband 18 | % can have only one coefficient. 19 | % 20 | %Example: 21 | % [ld,hd,N]= subband_dim(9, 3); %if upper_limit = 1 -> ld = 2, hd = 1 22 | % [ld,hd,N]= subband_dim(100, Inf); %for max. number of decompositions 23 | 24 | sdim = double(sdim); 25 | ld = zeros(size(sdim)); 26 | hd = zeros(size(sdim)); 27 | n = zeros(size(sdim)); 28 | 29 | for d=1:length(sdim) 30 | if (sdim(d) == 1) %singleton dimension, skip it! 31 | ld(d) = 1; 32 | hd(d) = 1; 33 | n(d) = N; 34 | else 35 | n(d) = sb_dim(sdim(d),N); 36 | end; 37 | end; 38 | 39 | N = min(n); 40 | for d=1:length(sdim) 41 | [n(d),ld(d),hd(d)] = sb_dim(sdim(d),N); 42 | end; 43 | 44 | function [i,ld,hd] = sb_dim(sdim,N) 45 | ld = sdim; 46 | hd = 0; 47 | for i=1:N 48 | ldold = ld; 49 | ld = ceil(ldold / 2); 50 | hd = ldold - ld; 51 | if (ld == 1) 52 | break; 53 | end; 54 | end; 55 | -------------------------------------------------------------------------------- /Wavelet/submatrix.m: -------------------------------------------------------------------------------- 1 | function [S,Sind] = submatrix(X,Ssiz,Soff) 2 | %Extracts submatrix from a multidimensional matrix 3 | %[S,Sind]=submatrix(X,Ssiz,Soff) 4 | % 5 | %Input: 6 | % X - matrix of n dimensions 7 | % Ssiz - submatrix size to be extracted 8 | % Soff - submatrix starts at this offset 9 | % 10 | %Output: 11 | % S - submatrix 12 | % Sind - indices of the extracted submatrix in the original submatrix 13 | % 14 | %Note: 15 | % To get the extracted indices use X(Sind{:}) 16 | % 17 | %Example: 18 | % Suppose I have an N-dimensional matrix X, and want to extract the 19 | % submatrix of which each dimension is half than in X (with 20 | % the offset at the first element of X). Then, the function would be called 21 | % with: S = submatrix(X,ceil(size(X)/2)); 22 | 23 | if isvector(X) 24 | n = 1; 25 | else 26 | n = ndims(X); 27 | end; 28 | if (nargin < 3) 29 | Soff = ones(n,1); %sets the default offset 30 | end; 31 | Sind = repmat({':'},n,1); 32 | for i = 1:n 33 | Sind{i} = Soff(i):(Soff(i) + Ssiz(i) - 1); 34 | end; 35 | S = X(Sind{:}); 36 | -------------------------------------------------------------------------------- /Wavelet/wavelet2D.m: -------------------------------------------------------------------------------- 1 | function W=wavelet2D(wavelet,iter,type,pass1,pass2) 2 | %Computes (and draws) a 2D wavelet, tensor product of 1D wavelets 3 | %W=wavelet2D(wavelet,iter,pass1,pass2,plt) 4 | % 5 | %Input: 6 | % wavelet - wavelet identification string 7 | % iter - number of successive approximation iterations 8 | % type - specifies wavelet 9 | % if (type == 'd') analysis (decomposition) filter 10 | % if (type == 'r') synthesis (reconstruction) filter 11 | % pass1, pass2 - specifies which row-column combination to take 12 | % if (pass1 == 'l' & pass2 == 'l') then LL 13 | % if (pass1 == 'l' & pass2 == 'h') then LH 14 | % if (pass1 == 'h' & pass2 == 'l') then HL 15 | % if (pass1 == 'h' & pass2 == 'h') then HH 16 | % 17 | %Output: 18 | % W - 2D wavelet 19 | % 20 | %Uses: 21 | % wavelet_fun.m 22 | % scaling_fun.m 23 | % 24 | %Example: 25 | % wavelet2D('CDF_9x7',5,'d','l','l'); 26 | % W=wavelet2D('LeGall_5x3',5,'d','l','l'); 27 | 28 | if nargin<=4 29 | plt = 0; 30 | else 31 | plt = 1; 32 | end; 33 | if (nargout > 0) %display only if output is not defined 34 | plt = ''; 35 | end; 36 | psi = []; %scaling function 37 | phi = []; %wavelet function 38 | 39 | if (pass1 == 'l') 40 | phi=scaling_fun(wavelet,iter,type); 41 | c1=phi; 42 | elseif (pass1=='h') 43 | psi=wavelet_fun(wavelet,iter,type); 44 | c1=psi; 45 | end; 46 | if (pass2=='l') 47 | if (isempty(phi)) 48 | phi=scaling_fun(wavelet,iter,type); 49 | end; 50 | c2=phi; 51 | elseif (pass2 == 'h') 52 | if (isempty(psi)) 53 | psi=wavelet_fun(wavelet,iter,type); 54 | end; 55 | c2=psi; 56 | end; 57 | 58 | W=c1'*c2; 59 | 60 | if (plt == 1) 61 | figure('NumberTitle','off','Name',[wavelet ' 2D wavelet']); 62 | opengl autoselect; 63 | surfl(W); 64 | axis([0 size(W,1) 0 size(W,1) min(min(W)) max(max(W))]); 65 | set(gca,'FontSize',15,'FontName','Times New Roman'); 66 | shading interp; 67 | colormap('copper'); 68 | rotate3d on; 69 | end; 70 | 71 | -------------------------------------------------------------------------------- /Wavelet/wavelet_9x7_char_freq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/wavelet_9x7_char_freq.png -------------------------------------------------------------------------------- /Wavelet/wavelet_9x7_char_phase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/wavelet_9x7_char_phase.png -------------------------------------------------------------------------------- /Wavelet/wavelet_check.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/wavelet_check.m -------------------------------------------------------------------------------- /Wavelet/wavelet_downscale.m: -------------------------------------------------------------------------------- 1 | function B=wavelet_downscale(A,wavelet,scale) 2 | %Image resizing performed by wavelet decomposition 3 | %B=wavelet_downscale(A,wavelet,scale) 4 | % 5 | %Input: 6 | % A - array containing an image 7 | % wavelet - wavelet identification string 8 | % scale - the scale the image is resized to (e.g. scale=1 halves the image 9 | % dimensions) 10 | % 11 | %Output: 12 | % B - downscaled image 13 | % 14 | %Uses: 15 | % dwt_dyadic_decomp.m 16 | % subband.m 17 | % 18 | %Example: 19 | % B=wavelet_downscale(A,'CDF_9x7',3); 20 | 21 | if scale == 0 22 | B = A; 23 | else 24 | if ischar(A) 25 | A=imread(A); 26 | end; 27 | A=double(A); 28 | D = dwt_dyadic_decomp(A,wavelet,scale); 29 | Dr = subband(D,scale,'ll'); 30 | B=Dr/(2^scale); %assumed that the DC gain factor is sqrt(2) 31 | B(B>255)=255; 32 | B(B<0)=0; 33 | B=uint8(round(B)); 34 | end; -------------------------------------------------------------------------------- /Wavelet/wavelet_fun.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/wavelet_fun.m -------------------------------------------------------------------------------- /Wavelet/wavelet_packet_subband_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/Wavelet/wavelet_packet_subband_tree.png -------------------------------------------------------------------------------- /YUV/BT601_219.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/YUV/BT601_219.mat -------------------------------------------------------------------------------- /YUV/BT601_f.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/YUV/BT601_f.mat -------------------------------------------------------------------------------- /YUV/BT601_l.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/YUV/BT601_l.mat -------------------------------------------------------------------------------- /YUV/BT709_f.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/YUV/BT709_f.mat -------------------------------------------------------------------------------- /YUV/BT709_l.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/YUV/BT709_l.mat -------------------------------------------------------------------------------- /YUV/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Nikola Sprljan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /YUV/README.md: -------------------------------------------------------------------------------- 1 | MATLAB YUV Toolbox 2 | ================== 3 | 4 | Functions for manipulation of YCbCr (also known as 'YUV') sequences. 5 | 6 | For YUV sequences comparison the Quality Assessment toolbox is required. For sequence rescaling and when rescaling chromas (e.g. conversion from 4:4:4 to 4:2:2) Matlab Image Processing Toolbox function imresize is used. 7 | 8 | 9 | Functions 10 | --------- 11 | 12 | - **divide_seq** - Divides YUV sequence into segments 13 | - **mm_seq** - Converts video file into raw YCbCr format 14 | - **read_floatframe** - Reads and displays frame values stored as a stream of float numbers 15 | - **rgb2yuv** - Converts RGB to YUV 16 | - **save_yuvframe** - Saves selected frame from yuv sequence to image file 17 | - **scale_seq** - Scales YUV sequence 18 | - **seq_frames** - Returns the number of frames in YUV sequence file 19 | - **shift_seq** - Artificially shifts a sequence in a defined direction by any displacement 20 | - **write_floatframe** - Stores matrix in a file as a stream of float numbers 21 | - **yuv2avi** - Imports YUV sequence and saves it as AVI 22 | - **yuv2rgb** - Converts YUV to RGB 23 | - **yuv_compare** - Compares two YUV sequences by computing PSNR 24 | - **yuv_export** - Exports YUV sequence 25 | - **yuv_import** - Imports YUV sequence 26 | - **yuv_range** - Computes the range of samples in YUV sequence 27 | 28 | Added: 29 | - **yuv2avi_demosaic - Imports YUV sequence, performs demosaic of each frame and saves it as an AVI 30 | - **yuv2seq_demosaic - Imports YUV sequence, performs demosaic of each frame and saves it as a sequence of images 31 | 32 | 33 | Examples 34 | -------- 35 | **yuv\_import**, **yuv2rgb**, **yuv\_compare**: 36 | 37 | >> [Y, U, V] = yuv_import('FOREMAN_352x288_30_orig_01.yuv',[352 288],2); 38 | >> rgb = yuv2rgb(Y{1},U{1},V{1}); 39 | >> [PY, PU, PV]=yuv_compare('compressed.yuv','original.yuv',[352 288]); 40 | -------------------------------------------------------------------------------- /YUV/SMPTE_240M.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/YUV/SMPTE_240M.mat -------------------------------------------------------------------------------- /YUV/TODO: -------------------------------------------------------------------------------- 1 | -support for higher bit-depths in rgb2yuv.m and yuv2rgb.m 2 | -support for different YUV formats in different functions, e.g. divide_seq.m, yuv_range.m 3 | -YUV format paramter generator function, to avoid replicating code across functions (bit precision, Y, U and V frame sizes...) 4 | -function to combine 2 sequences (YUV interleave / merge) 5 | -Investigate these colour transform definitions: 6 | 1) I709 (= Rec.709 coefficients) 7 | 2) FCC (almost the same as Rec.601) 8 | 3) I470 (= Rec.601 coefficients [an updated version of Rec.470-6, but coefficients are exactly the same]) 9 | 4) S170 (= SMPTE 170M; exactly the same as Rec.601) 10 | 11 | -------------------------------------------------------------------------------- /YUV/divide_seq.m: -------------------------------------------------------------------------------- 1 | function divide_seq(filename,dims,frstep) 2 | %Divides YUV sequence into segments 3 | %divide_seq(filename,dims,frstep) 4 | % 5 | %Input: 6 | % filename - YUV sequence file 7 | % dims - dimensions of the frame [width height] 8 | % frstep - number of frames in one segment 9 | % 10 | %Uses: 11 | % seq_frames.m 12 | % yuv_import.m 13 | % yuv_export.m 14 | % 15 | %Examples: 16 | % divide_seq('football.yuv',[352 288],8); 17 | 18 | [pathstr,name,ext] = fileparts(filename); 19 | numframes = seq_frames(filename,dims); 20 | part = 1; 21 | for i=1:frstep:numframes 22 | firstfr = i; 23 | lastfr = min(i + frstep - 1, numframes); 24 | frs = lastfr - firstfr + 1; 25 | [Y,U,V] = yuv_import(filename,dims,frs,i-1); 26 | partname = [pathstr '\' name '_GOP' num2str(part,'%02d') ext]; 27 | yuv_export(Y,U,V,partname,frs); 28 | part = part + 1; 29 | end; -------------------------------------------------------------------------------- /YUV/mm2yuv.m: -------------------------------------------------------------------------------- 1 | function mm2yuv(inputmm,outputyuv,yuvformat) 2 | %Converts video file into raw YCbCr format 3 | %mm2yuv(inputmm,outputyuv,yuvformat) 4 | % 5 | %Input: 6 | % inputmm - input multimedia file (e.g. avi, mpg, etc.) 7 | % outputyuv - output yuv file 8 | % yuvformat - [optional, default = 'YUV420_8']. YUV format, supported formats 9 | % are defined in yuv_import.m 10 | % 11 | %Example: 12 | % mm2yuv('input.avi','output.yuv','YUV444_8'); 13 | 14 | if (nargin < 3) 15 | yuvformat = 'YUV420_8'; 16 | end; 17 | M = mmreader(inputmm); 18 | outfile = outputyuv; 19 | for f = 1 : M.NumberOfFrames 20 | Mframe = read(M, f); 21 | R = Mframe(:,:,1); 22 | G = Mframe(:,:,2); 23 | B = Mframe(:,:,3); 24 | [Y{1},U{1},V{1}]=rgb2yuv(R,G,B,yuvformat); 25 | yuv_export(Y,U,V,outfile,1); 26 | end; 27 | -------------------------------------------------------------------------------- /YUV/read_floatframe.m: -------------------------------------------------------------------------------- 1 | function X=read_floatframe(filename,dims,disp) 2 | %Reads and displays frame values stored as a stream of float numbers 3 | %X=read_floatframe(filename,dims,disp) 4 | % 5 | %Input: 6 | % filename - file that contains the frame 7 | % dims - dimensions of the frame [height width] 8 | % disp - [optional, default = 1] specifies whether to display the output 9 | % if (disp ~= 0) then display 10 | % if (disp == 0) then do not display 11 | % 12 | %Output: 13 | % X - array of numbers containing the frame elements 14 | % 15 | %Uses: 16 | % image_show.m (Quality Assessment Toolbox) 17 | % 18 | %Example: 19 | % X = read_floatframe('GOP000_TFrame_0_01_L_Y',[576 704]); 20 | 21 | if nargin<3 %display by default 22 | disp=1; 23 | end; 24 | 25 | fid=fopen(filename,'r'); 26 | if (fid < 0) 27 | error('File does not exist!'); 28 | end; 29 | X = fread(fid,[dims(2) dims(1)],'float32'); 30 | fclose(fid); 31 | X=X'; 32 | if (disp == 1) 33 | image_show(X,256,1,filename); %comment out this to disable displaying 34 | %imwrite(I,gray(256),[filename '.png'],'png'); %uncomment this line to save as png image 35 | end; -------------------------------------------------------------------------------- /YUV/rgb2yuv.m: -------------------------------------------------------------------------------- 1 | function [Y,U,V]=rgb2yuv(R,G,B,yuvformat,convmtrx) 2 | %Converts RGB to YUV 3 | %[Y,U,V]=rgb2yuv(R,G,B,yuvformat) 4 | % 5 | %Input: 6 | % R,G,B - R,G and B components of the frame 7 | % yuvformat - YUV format [optional, default = 'YUV444_8']. Supported YUV 8 | % formats are: 9 | % 'YUV444_8' = 4:4:4 sampling, 8-bit precision (default) 10 | % 'YUV420_8' = 4:2:0 sampling, 8-bit precision 11 | % convmtrx - Conversion matrix [optional, default = 'BT709_l']. The 12 | % following conversions ase defined (see in Notes for more 13 | % details): 14 | % 'BT601_f' = ITU-R BT.601, RGB full [0...255] (in BT601_f.mat) 15 | % 'BT601_219' = ITU-R BT.601, RGB limited [0...219] (in 16 | % BT601_219.mat) 17 | % 'BT601_l' = ITU-R BT.601, RGB limited [16...235] (in BT601_l.mat) 18 | % 'BT709_f' = ITU-R BT.709, RGB limited [0...255] (in BT709_f.mat) 19 | % 'BT709_l' = ITU-R BT.709, RGB limited [16...235] (in BT709_l.mat) 20 | % 'SMPTE_240M' = SMPTE 240M (almost the same as Rec.709) 21 | % 22 | %Output: 23 | % Y,U,V - Y,U and V components of the frame 24 | % 25 | %Uses: 26 | % imresize.m - Matlab Image Processing Toolbox (when formats other than 27 | % 4:4:4 used) 28 | % 29 | %Note: 30 | % Note that a more correct term for what is here called YUV would be YCbCr, 31 | % since it is used for YUV representation in digital domain. Also, the R, G 32 | % and B components are actually non-linear because of gamma correction, and 33 | % are more correctly denoted as R', G' and B'. YCbCr is expected to be in 34 | % the range (below that is "footroom" range and above is "headroom"): 35 | % Y = [16...235] 36 | % Cb,Cr = [16...240] 37 | % 38 | % Some more details on the defined conversions follow. 39 | % ITU-R BT.601 - for SD (720x576) and lower resolutions. Three versions are 40 | % available: 41 | % 1) RGB in full range [0...255], rgb2yuvT matrix: 42 | % 0.257 0.504 0.098 43 | % -0.148 -0.291 0.439 44 | % 0.439 -0.368 -0.071 45 | % yuvoffset = [16; 128; 128] 46 | % (Resulting output range is Y=[16...235];Cb=[16...240];Cr=[16...240] 47 | % (Coefficients taken from [3],[4],[5],[6]. Integer implementation in [7]) 48 | % 49 | % 2) RGB limited to [0...219], rgb2yuvT matrix: 50 | % 0.299 0.587 0.114 51 | % -0.173 -0.339 0.511 52 | % 0.511 -0.428 -0.083 53 | % yuvoffset = [16; 128; 128] 54 | % (Resulting output range is Y=[16...235];Cb=[16...240];Cr=[16...240]) 55 | % (Note that in [1] the coeffcients are rounded to the nearest integer, 56 | % while the coefficients here are from [4] and [6]. If original signal is in 57 | % range [16...235] then offset of 16 for Y signal is not necessary, e.g. 58 | % definition from [6]) 59 | % 3) RGB limited to [16...235], rgb2yuvT matrix: 60 | % 0.299 0.587 0.114 61 | % -0.169 -0.331 0.500 62 | % 0.500 -0.419 -0.081 63 | % yuvoffset = [0; 128; 128] 64 | % (Resulting output range is Y=[16...235];Cb=[18.5...237.5];Cr=[18.5...237.5]) 65 | % (This conversion is also used in JPEG, which allows the input to be in the 66 | % full [0...255] range, where the output is in range Y=[0...255]; 67 | % Cb=[0.5...255.5];Cr=[0.5...255.5]) 68 | % (Coefficients taken from [1],[3]) 69 | % 70 | % ITU-R BT.709 - for HD resolutions (i.e. higher than SD). Two versions are 71 | % available: 72 | % 1) RGB in full range [0...255], rgb2yuvT matrix: 73 | % 0.1826 0.6142 0.0620 74 | % -0.1006 -0.3386 0.4392 75 | % 0.4392 -0.3989 -0.0403 76 | % yuvoffset = [16; 128; 128] 77 | % (Resulting output range is Y=[16...235];Cb=[16...240];Cr=[16...240]) 78 | % (Coefficients taken from [5], less precise version in [6]. Appears to be a 79 | % scaled version of the next one, where RGB is limited.) 80 | % 81 | % 2) RGB limited to [16...235], rgb2yuvT matrix: 82 | % 0.2126 0.7152 0.0722 83 | % -0.1146 -0.3854 0.5000 84 | % 0.5000 -0.4542 -0.0468 85 | % yuvoffset = [0; 128; 128] 86 | % (Resulting output range is Y=[16...235];Cb=[18.5...237.5];Cr=[18.5...237.5]) 87 | % (Coefficients taken from [2]. The ones in [6] are slightly different, for no 88 | % obvious reason) 89 | % 90 | % References: 91 | % [1] Rec. ITU-R BT.601-6 92 | % [2] Rec. ITU-R BT.709-5 93 | % [3] http://en.wikipedia.org/wiki/YCbCr 94 | % [4] http://www.poynton.com/ColorFAQ.html 95 | % [5] http://www.mathworks.com/access/helpdesk/help/toolbox/vipblks/ref/colorspaceconversion.html 96 | % [6] Keith Jack, Video Demystified, Chapter 3, http://www.compression.ru/download/articles/color_space/ch03.pdf 97 | % [7] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddraw/html/_dxce_converting_between_yuv_and_rgb.asp 98 | % 99 | %Example: 100 | % yuv = rgb2yuv(R,G,B,'YUV420_8','BT709_f'); 101 | 102 | if (nargin < 4) 103 | yuvformat = 'YUV444_8'; 104 | end; 105 | if (nargin < 5) 106 | convmtrx = 'BT709_l'; 107 | end; 108 | if (strcmp(yuvformat,'YUV420_8') && (exist('imresize','file') ~= 2)) 109 | error('For YUV420 subsampling rgb2yuv requires Image Processing Toolbox (TM) function imresize!'); 110 | end; 111 | 112 | if strcmp(convmtrx,'BT601_f') 113 | load('BT601_f.mat','-mat'); 114 | elseif strcmp(convmtrx,'BT601_l') 115 | load('BT601_l.mat','-mat'); 116 | elseif strcmp(convmtrx,'BT601_219') 117 | load('BT601_219.mat','-mat'); 118 | elseif strcmp(convmtrx,'BT709_f') 119 | load('BT709_f.mat','-mat'); 120 | elseif strcmp(convmtrx,'BT709_l') 121 | load('BT709_l.mat','-mat'); 122 | elseif strcmp(convmtrx,'SMPTE_240M') 123 | load('SMPTE_240M.mat','-mat'); 124 | end; 125 | 126 | T = rgb2yuvT; 127 | R = double(R); 128 | G = double(G); 129 | B = double(B); 130 | Y = T(1,1) * R + T(1,2) * G + T(1,3) * B + yuvoffset(1); 131 | U = T(2,1) * R + T(2,2) * G + T(2,3) * B + yuvoffset(2); 132 | V = T(3,1) * R + T(3,2) * G + T(3,3) * B + yuvoffset(3); 133 | if (strcmp(yuvformat,'YUV420_8')) 134 | U = imresize(U,0.5,'bicubic'); 135 | V = imresize(V,0.5,'bicubic'); 136 | elseif (strcmp(yuvformat,'YUV444_8')) 137 | %do nothing, already in the correct subsampling format 138 | end; 139 | Y = uint8(round(Y)); 140 | U = uint8(round(U)); 141 | V = uint8(round(V)); 142 | 143 | %Alternative conversion, as in [7], defined with: 144 | % C = Y - 16 145 | % D = U - 127 146 | % E = V - 128 147 | % R = clip(( 298 * C + 409 * E + 128) >> 8) 148 | % G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) 149 | % B = clip(( 298 * C + 516 * D + 128) >> 8) 150 | %yuv(:,:,1) = yuv(:,:,1) - 16; 151 | %yuv(:,:,2) = yuv(:,:,2) - 128; 152 | %yuv(:,:,3) = yuv(:,:,3) - 128; 153 | %rgb(:,:,1) = uint8(floor((298*yuv(:,:,1) + 409*yuv(:,:,3) + 128)/256)); 154 | %rgb(:,:,2) = uint8(floor((298*yuv(:,:,1) - 100*yuv(:,:,3) - 208*yuv(:,:,2))/256)); 155 | %rgb(:,:,3) = uint8(floor((298*yuv(:,:,1) + 516*yuv(:,:,2) + 128)/256)); -------------------------------------------------------------------------------- /YUV/save_yuvframe.m: -------------------------------------------------------------------------------- 1 | function [C,Y,U,V]=save_yuvframe(yuvfile,dims,frm,outimage) 2 | %Saves selected frame from yuv sequence to image file 3 | %[C,Y,U,V]=save_yuvframe(yuvfile,dims,frm,outimage) 4 | % 5 | %Input: 6 | % yuvfile - YUV sequence file 7 | % dims - dimensions of the frame [width height] 8 | % frm - frame to be converted, with the convention that the first frame of 9 | % the sequence is denoted with 0 10 | % outimage - output image file, the extension specifies the format. If 11 | % extension is not specified, save as raw, each componenet 12 | % independently using 8 bits per pixel. 13 | % 14 | %Output: 15 | % C - 3D RGB matrix, see help in yuv2rgb.m 16 | % Y, U, V - each component 17 | % 18 | %Uses: 19 | % yuv_import.m (for reading a frame from the yuv file) 20 | % yuv2rgb.m (for converting to RGB color system) 21 | % 22 | %Example: 23 | % C = save_yuvframe('foreman.yuv',[352 288],1,'foreman_1stframe.png'); 24 | 25 | [Y, U, V] = yuv_import(yuvfile,dims,1,frm); 26 | [t1,t2,ext] = fileparts(outimage); 27 | C = []; 28 | if (isempty(ext)) 29 | fid=fopen([outimage 'Y.raw'],'w'); 30 | fwrite(fid,Y{1}','uint8'); 31 | fclose(fid); 32 | fid=fopen([outimage 'U.raw'],'w'); 33 | fwrite(fid,U{1}','uint8'); 34 | fclose(fid); 35 | fid=fopen([outimage 'V.raw'],'w'); 36 | fwrite(fid,V{1}','uint8'); 37 | fclose(fid); 38 | %yuv_export(Y,U,V,[outimage '.raw'], 1); 39 | else %save as image, using the specified extension to determine the format 40 | C=yuv2rgb(Y{1},U{1},V{1}); 41 | imwrite(C,outimage); 42 | end; 43 | -------------------------------------------------------------------------------- /YUV/seq_frames.m: -------------------------------------------------------------------------------- 1 | function frames=seq_frames(filename,dims,yuvformat) 2 | %Returns the number of frames in YUV sequence file 3 | %frames=seq_frames(filename,dims,format) 4 | % 5 | %Input: 6 | % filename - YUV sequence file 7 | % dims - dimensions of the frame [width height] 8 | % yuvformat - YUV format [optional, default = 'YUV420_8']. Supported YUV 9 | % formats are: 10 | % 'YUV444_8' = 4:4:4 sampling, 8-bit precision 11 | % 'YUV420_8' = 4:2:0 sampling, 8-bit precision (default) 12 | % 13 | %Examples: 14 | % frames = seq_frames('football.yuv',[352 288],'420'); 15 | 16 | if (nargin < 3) 17 | yuvformat = 'YUV420_8'; 18 | end; 19 | 20 | Ysiz = prod(dims); 21 | if strcmp(yuvformat,'YUV420_8') 22 | UVsiz = Ysiz / 4; 23 | frelem = Ysiz + 2*UVsiz; 24 | elseif strcmp(yuvformat,'YUV444_8') 25 | frelem = 3*Ysiz; 26 | else 27 | error(['Format ' format ' not supported or unknown!']); 28 | end; 29 | fid=fopen(filename,'r'); 30 | if (fid == -1) 31 | error('Cannot open file'); 32 | end; 33 | fseek(fid, 0, 'eof'); 34 | yuvbytes = ftell(fid); 35 | frames = floor(yuvbytes / frelem); 36 | fclose(fid); 37 | -------------------------------------------------------------------------------- /YUV/shift_seq.m: -------------------------------------------------------------------------------- 1 | function shift_seq(filename,dims,frame,numfrm,startw,dimw,shiftw,outfilename) 2 | %Artificially shifts a sequence in a defined direction by any displacement 3 | %shift_seq(filename,dims,frame,numfrm,startw,dimw,shiftw,outfilename) 4 | % 5 | %Input: 6 | % filename - YUV sequence file 7 | % dims - dimensions of the frame [width height] 8 | % frame - which frame to take 9 | % numfrm - number of frames to generate 10 | % startw - left upper coordinate of the window to be shifted 11 | % dimw - window dimension (part of the frame to be shifted) 12 | % shiftw - number of pixels to move the window per one frame 13 | % outfilename - filename of the output YUV sequence 14 | % 15 | %Uses: 16 | % yuv_import.m (for reading a frame from the yuv file) 17 | % yuv_export.m (for storing a frame to the yuv file) 18 | % 19 | %Example: 20 | % shift_seq('CITY_704x576_30_orig_01.yuv',[704 576],1,16,[100 100],[352 288],[0.5 0.5],'shiftcity.yuv'); 21 | 22 | [Y, U, V] = yuv_import(filename,dims,1,frame); 23 | 24 | scol = shiftw(1); %shift columns 25 | srow = shiftw(2); %shift rows 26 | wcolY = dimw(1); %window columns luma 27 | wrowY = dimw(2); %window rows luma 28 | wcolC = dimw(1)/2; %window columns chroma 29 | wrowC = dimw(2)/2; %window rows chroma 30 | wstr = startw(2); 31 | wstc = startw(1); 32 | 33 | %for interpolation 34 | [xY,yY] = meshgrid(1:dims(1),1:dims(2)); 35 | [xC,yC] = meshgrid(1:dims(1)/2,1:dims(2)/2); 36 | 37 | for i=0:numfrm-1 38 | stepr = i*srow; 39 | stepc = i*scol; 40 | sr = stepr + wstr; 41 | sc = stepc + wstc; 42 | if ((floor(sr) == sr) && (floor(sc) == sc)) 43 | Yr{1} = Y{1}(sr:wrowY+sr-1,sc:wcolY+sc-1); 44 | else 45 | [XI,YI] = meshgrid(sc:wcolY+sc-1,sr:wrowY+sr-1); 46 | Yr{1} = interp2(xY,yY,Y{1},XI,YI,'spline'); 47 | end; 48 | sr = double(sr) / 2; 49 | sc = double(sc) / 2; 50 | if ((floor(sr) == sr) && (floor(sc) == sc)) 51 | Ur{1} = U{1}(sr:wrowC+sr-1,sc:wcolC+sc-1); 52 | Vr{1} = V{1}(sr:wrowC+sr-1,sc:wcolC+sc-1); 53 | else 54 | [XI,YI] = meshgrid(sc:wcolC+sc-1,sr:wrowC+sr-1); 55 | Ur{1} = interp2(xC,yC,U{1},XI,YI,'spline'); 56 | Vr{1} = interp2(xC,yC,V{1},XI,YI,'spline'); 57 | end; 58 | yuv_export(Yr,Ur,Vr,outfilename,1); 59 | fprintf('Frame %d/%d\n',i+1,numfrm); 60 | end; 61 | 62 | -------------------------------------------------------------------------------- /YUV/write_floatframe.m: -------------------------------------------------------------------------------- 1 | function write_floatframe(filename,A) 2 | %Stores matrix in a file as a stream of float numbers 3 | %write_floatframe(filename,A) 4 | % 5 | %Input: 6 | % filename - file in which the matrix will be saved 7 | % A - array to be saved 8 | % 9 | %Example: 10 | % write_floatframe('Afloat',A); 11 | 12 | fid=fopen(filename,'w'); 13 | if (fid < 0) 14 | error('Cannot create file!'); 15 | end; 16 | fwrite(fid,A(:),'float32'); 17 | fclose(fid); -------------------------------------------------------------------------------- /YUV/yuv2avi.m: -------------------------------------------------------------------------------- 1 | function numfrm=yuv2avi(yuvfilename,dims,avifilename,fps,yuvformat) 2 | %Imports YUV sequence and saves it as an AVI 3 | %numfrm=yuv2avi(yuvfilename,dims,avifilename,fps) 4 | % 5 | %Input: 6 | % yuvfilename - YUV sequence file 7 | % dims - dimensions of the frame [width height] 8 | % avifilename - name of the output AVI file 9 | % fps - frames per second 10 | % yuvformat - [optional, default = 'YUV420_8']. YUV format, supported formats 11 | % are defined in yuv_import.m. The default conversion matrix is 12 | % ITU-R BT.709, see in yuv2rgb.m and rgb2yuv.m 13 | % 14 | %Output: 15 | % numfrm - number of frames processed 16 | % 17 | %Uses: 18 | % yuv2rgb.m (for converting into RGB) 19 | % yuv_import.m (for importing the YUV frames) 20 | % imresize.m (Matlab Image Toolbox) 21 | % 22 | %Example: 23 | % numfrm = yuv2avi('city_CIF.yuv',[352 288],'test.avi',15,'YUV444_8'); 24 | 25 | if (nargin < 6) 26 | yuvformat = 'YUV420_8'; 27 | end; 28 | if (strcmp(yuvformat,'YUV420_8') && (exist('imresize','file') ~= 2)) 29 | error('For YUV420 subsampling yuv2avi requires Image Processing Toolbox (TM) function imresize!'); 30 | end; 31 | 32 | numfrm = seq_frames(yuvfilename,dims); 33 | 34 | % Create AVI file 35 | avi = VideoWriter(avifilename); 36 | set(avi, 'FrameRate', fps); 37 | set(avi, 'Quality', 100); 38 | 39 | open(avi); 40 | for i = 1 : 60 41 | % Import YUV frame 42 | [Y, U, V] = yuv_import(yuvfilename,dims,1,i-1,yuvformat); 43 | % Convert YUV to RGB 44 | rgb = yuv2rgb(Y{1},U{1},V{1},yuvformat); 45 | % Save frame to file 46 | writeVideo(avi, rgb); 47 | 48 | fprintf('Frame %d/%d\n',i,numfrm); 49 | end; 50 | close(avi); 51 | -------------------------------------------------------------------------------- /YUV/yuv2avi_demosaic.m: -------------------------------------------------------------------------------- 1 | function numfrm=yuv2avi_demosaic(yuvFilename, dims, aviFilename, varargin) 2 | %Imports YUV sequence, performs demosaic of each frame and saves it as an AVI 3 | %numfrm=yuv2avi_demosaic(yuvFilename, dims, aviFilename, fps, sensorAlignment, yuvFormat) 4 | % 5 | %Input: 6 | % yuvFilename - YUV sequence file 7 | % dims - dimensions of the frame [width height] 8 | % aviFilename - name of the output AVI file 9 | % fps - [optional, default = 30] frames per second 10 | % sensorAlignment - [optional, default = 'rggb'] Bayer pattern, see demosaic() 11 | % yuvFormat - [optional, default = 'YUV420_8']. YUV format, supported formats 12 | % are defined in yuv_import.m. The default conversion matrix is 13 | % ITU-R BT.709, see in yuv2rgb.m and rgb2yuv.m 14 | % 15 | %Output: 16 | % numfrm - number of frames processed 17 | % 18 | %Uses: 19 | % yuv2rgb.m (for converting into RGB) 20 | % yuv_import.m (for importing the YUV frames) 21 | % 22 | %Example: 23 | % numfrm = yuv2avi_demosaic('city_CIF.yuv', [352, 288], 'test.avi', 15, 'bggr', 'YUV444_8'); 24 | % numfrm = yuv2avi_demosaic('yuv_file.yuv', [640, 480], 'avi_file.avi'); 25 | 26 | % Validate inputs 27 | inputs = inputParser; 28 | expectedPatterns = {'gbrg', 'grbg', 'bggr', 'rggb'}; 29 | expectedYuvFormats = {'YUV444_8', 'YUV420_8', 'YUV420_16'}; 30 | 31 | inputs.addRequired('yuvFilename'); 32 | inputs.addRequired('dims'); 33 | inputs.addRequired('aviFilename'); 34 | inputs.addOptional('fps', 30); 35 | inputs.addOptional('sensorAlignment', 'rggb', @(pattern) any(validatestring(pattern, expectedPatterns))); 36 | inputs.addOptional('yuvFormat', 'YUV420_8', @(format) any(validatestring(format, expectedYuvFormats))); 37 | inputs.parse(yuvFilename, dims, aviFilename, varargin{:}); 38 | 39 | % Get number of frames to process 40 | numfrm = seq_frames(yuvFilename, dims); 41 | 42 | % Create AVI file 43 | avi = VideoWriter(aviFilename); 44 | set(avi, 'FrameRate', inputs.Results.fps); 45 | set(avi, 'Quality', 100); 46 | 47 | open(avi); 48 | for i = 1 : numfrm 49 | % Import YUV frame 50 | [Y, U, V] = yuv_import(yuvFilename, dims, 1, i - 1, inputs.Results.yuvFormat); 51 | % Convert YUV to RGB 52 | rgb = yuv2rgb(Y{1}, U{1}, V{1}, inputs.Results.yuvFormat); 53 | 54 | % Perform demosaic 55 | rgbGray = rgb2gray(rgb); 56 | rgbFrame = demosaic(rgbGray, inputs.Results.sensorAlignment); 57 | 58 | % Save frame 59 | writeVideo(avi, rgbFrame); 60 | 61 | fprintf('Frame %d/%d\n',i,numfrm); 62 | end; 63 | close(avi); 64 | -------------------------------------------------------------------------------- /YUV/yuv2rgb.m: -------------------------------------------------------------------------------- 1 | function rgb=yuv2rgb(Y,U,V,yuvformat,convmtrx) 2 | %Converts YUV to RGB 3 | %rgb=yuv2rgb(Y,U,V,yuvformat,convmtrx) 4 | % 5 | %Input: 6 | % Y,U,V - Y,U and V components of the frame 7 | % yuvformat - YUV format [optional, default = 'YUV420_8']. See in rgb2yuv.m 8 | % for supported YUV subsampling formats. 9 | % convmtrx - Conversion matrix [optional, default = 'BT709_l']. The 10 | % following conversions ase defined. See in rgb2yuv.m 11 | % for more details. 12 | % 13 | %Output: 14 | % rgb - RGB 3D matrix. rgb(:,:,1), rgb(:,:,2) and rgb(:,:,3) are R, G and 15 | % B components, respectively. 16 | % 17 | %Uses: 18 | % imresize.m - Matlab Image Processing Toolbox 19 | % 20 | %Note: 21 | % When the input format has the chroma subsampled (e.g. 4:2:0 format), 22 | % upsampling is employed on the chroma components before the conversion 23 | % takes place. 24 | % See in the help of rgb2yuv.m for details on coversion options. 25 | % 26 | % ITU-R BT.601, RGB full range, results in the following transform matrix: 27 | % 1.164 0.000 1.596 28 | % 1.164 -0.392 -0.813 29 | % 1.164 2.017 0.000 30 | % ITU-R BT.601, RGB limited range, results in the following transform matrix: 31 | % 1.000 0.000 1.402 32 | % 1.000 -0.344 -0.714 33 | % 1.000 1.772 0.000 34 | % ITU-R BT.709, RGB limited range, results in the following transform matrix: 35 | % 1.000 0.000 1.570 36 | % 1.000 -0.187 -0.467 37 | % 1.000 1.856 0.000 38 | % 39 | %Example: 40 | % rgb = yuv2rgb(Y,U,V); 41 | 42 | if (nargin < 4) 43 | yuvformat = 'YUV420_8'; 44 | end; 45 | if (nargin < 5) 46 | convmtrx = 'BT709_l'; 47 | end; 48 | if (strcmp(yuvformat,'YUV420_8') && (exist('imresize','file') ~= 2)) 49 | error('For YUV420 subsampling yuv2rgb requires Image Processing Toolbox (TM) function imresize!'); 50 | end; 51 | 52 | if strcmp(convmtrx,'BT601_f') 53 | load('BT601_f.mat','-mat'); 54 | elseif strcmp(convmtrx,'BT601_l') 55 | load('BT601_l.mat','-mat'); 56 | elseif strcmp(convmtrx,'BT601_219') 57 | load('BT601_219.mat','-mat'); 58 | elseif strcmp(convmtrx,'BT709_f') 59 | load('BT709_f.mat','-mat'); 60 | elseif strcmp(convmtrx,'BT709_l') 61 | load('BT709_l.mat','-mat'); 62 | end; 63 | 64 | %create the 3D YUV array 65 | yuv = zeros(size(Y,1),size(Y,2),3); 66 | if (strcmp(yuvformat,'YUV420_8')) 67 | yuv(:,:,1) = double(Y); 68 | yuv(:,:,2) = imresize(double(U),2,'bicubic'); 69 | yuv(:,:,3) = imresize(double(V),2,'bicubic'); 70 | elseif (strcmp(yuvformat,'YUV444_8')) 71 | yuv(:,:,1) = double(Y); 72 | yuv(:,:,2) = double(U); 73 | yuv(:,:,3) = double(V); 74 | end; 75 | 76 | %inversion of the transform matrix 77 | T = inv(rgb2yuvT); 78 | rgb = zeros(size(Y,1),size(Y,2),3); 79 | if (yuvoffset(1) ~= 0) 80 | yuv(:,:,1) = yuv(:,:,1) - yuvoffset(1); 81 | end; 82 | if (yuvoffset(2) ~= 0) 83 | yuv(:,:,2) = yuv(:,:,2) - yuvoffset(2); 84 | end; 85 | if (yuvoffset(3) ~= 0) 86 | yuv(:,:,3) = yuv(:,:,3) - yuvoffset(3); 87 | end; 88 | rgb(:,:,1) = T(1,1) * yuv(:,:,1) + T(1,2) * yuv(:,:,2) + T(1,3) * yuv(:,:,3); 89 | rgb(:,:,2) = T(2,1) * yuv(:,:,1) + T(2,2) * yuv(:,:,2) + T(2,3) * yuv(:,:,3); 90 | rgb(:,:,3) = T(3,1) * yuv(:,:,1) + T(3,2) * yuv(:,:,2) + T(3,3) * yuv(:,:,3); 91 | rgb = uint8(round(rgb)); -------------------------------------------------------------------------------- /YUV/yuv2seq_demosaic.m: -------------------------------------------------------------------------------- 1 | function numfrm=yuv2seq_demosaic(yuvFilename, dims, imagesDir, varargin) 2 | %Imports YUV sequence, performs demosaic of each frame and saves it as a 3 | %sequence of images 4 | %numfrm=yuv2avi_demosaic(yuvFilename, dims, imagesDir, imageNamePattern, sensorAlignment, yuvFormat) 5 | % 6 | %Input: 7 | % yuvFilename - YUV sequence file 8 | % dims - dimensions of the frame [width height] 9 | % imagesDir - name of the directory for output images 10 | % sensorAlignment - [optional, default = 'rggb'] Bayer pattern, see demosaic() 11 | % imageNamePattern - [optional, default = 'Frame_%05d.png'] name pattern 12 | % for images (default prints always five digits as an index) 13 | % yuvFormat - [optional, default = 'YUV420_8']. YUV format, supported formats 14 | % are defined in yuv_import.m. The default conversion matrix is 15 | % ITU-R BT.709, see in yuv2rgb.m and rgb2yuv.m 16 | % 17 | %Output: 18 | % numfrm - number of frames processed 19 | % 20 | %Uses: 21 | % yuv2rgb.m (for converting into RGB) 22 | % yuv_import.m (for importing the YUV frames) 23 | % 24 | %Example: 25 | % numfrm = yuv2avi_demosaic('yuv_file.yuv', [640, 480], 'C:\output'); 26 | % numfrm = yuv2avi_demosaic('yuv_file.yuv', [640, 480], 'C:\output', 'bggr', 'rgb_%03d.png', 'YUV444_8'); 27 | 28 | % Validate inputs 29 | inputs = inputParser; 30 | expectedPatterns = {'gbrg', 'grbg', 'bggr', 'rggb'}; 31 | expectedYuvFormats = {'YUV444_8', 'YUV420_8', 'YUV420_16'}; 32 | 33 | inputs.addRequired('yuvFilename'); 34 | inputs.addRequired('dims'); 35 | inputs.addRequired('imagesDir'); 36 | inputs.addOptional('imageNamePattern', 'Frame_%05d.png', @(pattern) not(isempty(pattern))); 37 | inputs.addOptional('sensorAlignment', 'rggb', @(pattern) any(validatestring(pattern, expectedPatterns))); 38 | inputs.addOptional('yuvFormat', 'YUV420_8', @(format) any(validatestring(format, expectedYuvFormats))); 39 | inputs.parse(yuvFilename, dims, imagesDir, varargin{:}); 40 | 41 | % Get number of frames to process 42 | numfrm = seq_frames(yuvFilename, dims); 43 | 44 | for i = 1 : numfrm 45 | % Import YUV frame 46 | [Y, U, V] = yuv_import(yuvFilename, dims, 1, i - 1, inputs.Results.yuvFormat); 47 | % Convert YUV to RGB 48 | rgb = yuv2rgb(Y{1}, U{1}, V{1}, inputs.Results.yuvFormat); 49 | 50 | % Perform demosaic 51 | rgbGray = rgb2gray(rgb); 52 | rgbFrame = demosaic(rgbGray, inputs.Results.sensorAlignment); 53 | 54 | % Save frame 55 | dest = strcat(imagesDir, '\', sprintf(inputs.Results.imageNamePattern, i)); 56 | imwrite(rgbFrame, dest); 57 | 58 | fprintf('Frame %d/%d\n', i, numfrm); 59 | end; 60 | -------------------------------------------------------------------------------- /YUV/yuv_compare.m: -------------------------------------------------------------------------------- 1 | function [PSNRY,PSNRU,PSNRV,MSEY,MSEU,MSEV]=yuv_compare(yuvfile1,yuvfile2,dims,frames1,frames2) 2 | %Compares two YUV sequences by computing PSNR 3 | %[PSNRY,PSNRU,PSNRV,MSEY,MSEU,MSEV]=yuv_compare(yuvfile1,yuvfile2,dims) 4 | % 5 | %Input: 6 | % yuvfile1 - first YUV sequence file 7 | % yuvfile2 - second YUV sequence file 8 | % dims - frame dimensions 9 | % frames1 - [optional, default = all frames] frames in yuvfile1 to compare 10 | % frames2 - [optional, default = frames1] frames in yuvfile2 to compare 11 | % 12 | %Output: 13 | % PSNRY, PSNRU, PSNRV - PSNR values of the sequence for each frame, for Y, 14 | % U and V, respectively 15 | % MSEY, MSEU, MSEV - the same, but MSE 16 | % 17 | %Uses: 18 | % seq_frames.m 19 | % yuv_import.m 20 | % iq_measures.m (Quality Assessment toolbox - computation of MSE and PSNR) 21 | % 22 | %Example: 23 | % [PY, PU, PV]=yuv_compare('compressed.yuv','original.yuv',[352 288]); 24 | 25 | numfrm1 = seq_frames(yuvfile1,dims); 26 | numfrm2 = seq_frames(yuvfile2,dims); 27 | if (nargin < 4) 28 | numfrm = min([numfrm1 numfrm2]); 29 | frames1 = 1:numfrm; 30 | end; 31 | if (nargin < 5) 32 | frames2 = frames1; %assumed that the sequence are temporally coincident 33 | end; 34 | numfrm = length(frames1); 35 | numfrm2 = length(frames2); 36 | if (numfrm ~= numfrm2) 37 | error('Different number of frames selected.'); 38 | end; 39 | PSNRY = zeros(numfrm,1);PSNRU = zeros(numfrm,1);PSNRV = zeros(numfrm,1); 40 | MSEY = zeros(numfrm,1);MSEU = zeros(numfrm,1);MSEV = zeros(numfrm,1); 41 | for i=1:numfrm 42 | 43 | [Y1, U1, V1] = yuv_import(yuvfile1,dims,1,frames1(i)-1); 44 | %if (numel(Y1{1}) ~= prod(frm)) 45 | % break; 46 | %end; %there's no more frames in the sequence 1 47 | [Y2, U2, V2] = yuv_import(yuvfile2,dims,1,frames2(i)-1); 48 | %if (numel(Y2{1}) ~= prod(frm)) 49 | % break; 50 | %end; %there's no more frames in the sequence 2 51 | [MSEY(i),PSNRY(i)] = iq_measures(Y1{1},Y2{1}); 52 | [MSEU(i),PSNRU(i)] = iq_measures(U1{1},U2{1}); 53 | [MSEV(i),PSNRV(i)] = iq_measures(V1{1},V2{1}); 54 | end; 55 | -------------------------------------------------------------------------------- /YUV/yuv_export.m: -------------------------------------------------------------------------------- 1 | function yuv_export(Y,U,V,filename,numfrm,mode) 2 | %Exports YUV sequence 3 | %yuv_export(Y,U,V,filename,numfrm) 4 | % 5 | %Input: 6 | % Y, U ,V - cell arrays of Y,U & V components 7 | % filename - name of the file in which YUV sequence is to be saved 8 | % numfrm - number of frames to write 9 | % mode - [optional, default = 'a'] file write mode, append 'a' or write 'w' 10 | % 11 | %Output: 12 | % Y, U ,V - cell arrays of Y, U and V components 13 | % 14 | %Note: 15 | % If the file already exists, the function appends frames 16 | % 17 | %Example: 18 | % [Y, U, V] = yuv_import('F:\Seq\FullSeqs\basket_704x576x4.yuv',[704 576],2); 19 | % yuv_export(Y,U,V,'seq_test.yuv',2); 20 | 21 | if nargin<6 22 | mode = 'a'; %append! 23 | end; 24 | fid=fopen(filename,mode); 25 | if (fid < 0) 26 | error('Could not open the file!'); 27 | end; 28 | for i=1:numfrm 29 | Yd = Y{i}'; 30 | fwrite(fid,Yd,'uint8'); 31 | UVd = U{i}'; 32 | fwrite(fid,UVd,'uint8'); 33 | UVd = V{i}'; 34 | fwrite(fid,UVd,'uint8'); 35 | end; 36 | fclose(fid); 37 | -------------------------------------------------------------------------------- /YUV/yuv_import.m: -------------------------------------------------------------------------------- 1 | function [Y,U,V]=yuv_import(filename,dims,numfrm,startfrm,yuvformat) 2 | %Imports YUV sequence 3 | %[Y,U,V]=yuv_import(filename,dims,numfrm,startfrm) 4 | % 5 | %Input: 6 | % filename - YUV sequence file 7 | % dims - dimensions of the frame [width height] 8 | % numfrm - number of frames to read 9 | % startfrm - [optional, default = 0] specifies from which frame to start reading 10 | % with the convention that the first frame of the sequence is 0- 11 | % numbered 12 | % yuvformat - [optional, default = 'YUV420_8']. YUV format, supported formats 13 | % are: 14 | % 'YUV444_8' = 4:4:4 sampling, 8-bit precision 15 | % 'YUV420_8' = 4:2:0 sampling, 8-bit precision 16 | % 'YUV420_16' = 4:2:0 sampling, 16-bit precision 17 | % 18 | %Output: 19 | % Y, U ,V - cell arrays of Y, U and V components 20 | % 21 | %Note: 22 | % Supported YUV formats are (corresponding yuvformat variable): 23 | % 'YUV420_8' = 4:2:0 sampling, 8-bit precision (default) 24 | % 'YUV420_16' = 4:2:0 sampling, 16-bit precision 25 | % 26 | %Example: 27 | % [Y, U, V] = yuv_import('FOREMAN_352x288_30_orig_01.yuv',[352 288],2); 28 | % image_show(Y{1},256,1,'Y component'); 29 | % [Y, U, V] = yuv_import('sequence.yuv',[1920 1080],2,0,'YUV420_16'); 30 | 31 | fid=fopen(filename,'r'); 32 | if (fid < 0) 33 | error('File does not exist!'); 34 | end; 35 | 36 | inprec = 'ubit8'; 37 | sampl = 420; 38 | if (nargin < 4) 39 | startfrm = 0; 40 | end; 41 | if (nargin < 5) 42 | yuvformat = 'YUV420_8'; 43 | end; 44 | 45 | if (strcmp(yuvformat,'YUV420_16')) 46 | inprec = 'uint16'; %'ubit16=>uint16' 47 | elseif (strcmp(yuvformat,'YUV444_8')) 48 | sampl = 444; 49 | end; 50 | 51 | if (sampl == 420) 52 | dimsUV = dims / 2; 53 | else 54 | dimsUV = dims; 55 | end; 56 | Yd = zeros(dims); 57 | UVd = zeros(dimsUV); 58 | frelem = numel(Yd) + 2*numel(UVd); 59 | 60 | fseek(fid, startfrm * frelem , 0); %go to the starting frame 61 | Y = cell(1,numfrm); 62 | U = cell(1,numfrm); 63 | V = cell(1,numfrm); 64 | for i=1:numfrm 65 | Yd = fread(fid,dims,inprec); 66 | Y{i} = Yd'; 67 | UVd = fread(fid,dimsUV,inprec); 68 | U{i} = UVd'; 69 | UVd = fread(fid,dimsUV,inprec); 70 | V{i} = UVd'; 71 | end; 72 | fclose(fid); 73 | -------------------------------------------------------------------------------- /YUV/yuv_range.m: -------------------------------------------------------------------------------- 1 | function [Yrange,Urange,Vrange]=yuv_range(yuvfile,dims) 2 | %Computes the range of samples in YUV sequence 3 | %[Yrange,Urange,Vrange]=yuv_range(yuvfile,dims) 4 | % 5 | %Input: 6 | % filename - YUV sequence file 7 | % dims - dimensions of the frame [width height] 8 | % 9 | %Output: 10 | % Yrange, Urange, Vrange - ranges of the components values 11 | % 12 | %Note: 13 | % Supports only the YUV420_8 format. 14 | % 15 | %Example: 16 | % [Yrange, Urange, Vrange] = yuv_range('FOREMAN_352x288_30_orig_01.yuv',[352 288]); 17 | 18 | numfrm = seq_frames(yuvfile,dims); 19 | Ymin = Inf; Ymax = -Inf; 20 | Umin = Inf; Umax = -Inf; 21 | Vmin = Inf; Vmax = -Inf; 22 | for i=1:numfrm 23 | [Y, U, V] = yuv_import(yuvfile,dims,1,i-1); 24 | %minimum 25 | Ymin = min(Ymin, min(Y{1}(:))); 26 | Umin = min(Umin, min(U{1}(:))); 27 | Vmin = min(Vmin, min(V{1}(:))); 28 | %maximum 29 | Ymax = max(Ymax, max(Y{1}(:))); 30 | Umax = max(Umax, max(U{1}(:))); 31 | Vmax = max(Vmax, max(V{1}(:))); 32 | end; 33 | Yrange = [Ymin Ymax]; 34 | Urange = [Umin Umax]; 35 | Vrange = [Vmin Vmax]; -------------------------------------------------------------------------------- /ZerotreeCoding/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Nikola Sprljan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /ZerotreeCoding/README.md: -------------------------------------------------------------------------------- 1 | Zerotree Coding Toolbox 2 | ======================= 3 | 4 | Image compression based on wavelets, using zerotrees of wavelet coefficients. Uses [Wavelet](https://github.com/nsprljan/ImageCodingResearchTools/tree/master/Wavelet) and [Quality Assessment](https://github.com/nsprljan/ImageCodingResearchTools/tree/master/QualityAssessment) toolboxes. The SPIHT binaries required for function spspiht.m can be downloaded from the SPIHT image compression homepage, see below. 5 | 6 | 7 | Functions 8 | --------- 9 | 10 | - **dead\_zone\_q** - Quantisation with a central dead-zone around zero 11 | - **ezw** - EZW (Embedded Zerotree Wavelet) image compression 12 | - **pdf_opt** - Optimisation (pdf) of reconstructed values of quantised wavelet coefficients 13 | - **spiht\_stream\_dec** - Performs decoding of the bitstream produced by spiht_wpackets.m 14 | - **spiht_wpackets** - SPIHT image compression using Wavelet Packets (WP) decomposition 15 | - **spspiht** - Script for batch execution of DOS SPIHT binaries 16 | 17 | DOS SPIHT binaries required for function spspiht.m can be found at [SPIHT image compression homepage](http://www.cipr.rpi.edu/research/SPIHT/spiht3.html). Here's [direct link](http://www.cipr.rpi.edu/research/SPIHT/EW_Code/SPIHT.zip) to the package. 18 | 19 | 20 | Examples 21 | -------- 22 | SPIHT algorithm flow-chart: 23 | 24 | ![SPIHT algorithm flow-chart](https://github.com/nsprljan/ImageCodingResearchTools/raw/master/ZerotreeCoding/SPIHT_flowchart.png) 25 | 26 | **spiht_wpackets** with dyadic DWT, as in the original SPIHT: 27 | 28 | >> [Arec,bitstream,PSNR]=spiht_wpackets('Lena512.png',[0.1 1],'CDF_9x7',6); 29 | 6 decompositions, 0 packet depth, CDF_9x7 wavelet, highest bitrate 1.000000 bpp 30 | Image transformed in 0.85 seconds 31 | Maximum magnitudes computed in 0.24 seconds 32 | 33 | SPIHT algorithm... 34 | 35 | 1. bitrate - 0.099995 bpp 36 | No. output bits - 26216(3277 bytes; 3 excess bits)-> 0.100006 bpp 37 | MSE (Mean Squared Error) = 68.231052 38 | PSNR (Peak Signal / Noise Ratio) = 29.790983 dB 39 | 40 | 2. bitrate - 0.999996 bpp 41 | No. output bits - 262144(32768 bytes; 1 excess bits)-> 1.000000 bpp 42 | MSE (Mean Squared Error) = 6.535866 43 | PSNR (Peak Signal / Noise Ratio) = 39.977772 dB 44 | 45 | ...LIS (checking children) loop out - completed in 8.91 seconds 46 | 47 | Statistics collected during encoding in **SPIHTlog.txt**, where 'bpc' stands for 'bits per significant coefficient': 48 | 49 | LIP loop LIS loop Total significant 50 | pass(start bit) bits/coeffs. bits/coeffs. coeffs.(LSP start bit) 51 | 1.( 52) 65/1 =65.00 bpc 64/0 = Inf bpc 1( 181) 52 | 2.( 181) 81/18 = 4.50 bpc 89/5 =17.80 bpc 24( 351) 53 | 3.( 352) 67/12 = 5.58 bpc 246/32 = 7.69 bpc 68( 665) 54 | 4.( 689) 150/39 = 3.85 bpc 749/111 = 6.75 bpc 218( 1588) 55 | 5.( 1656) 362/80 = 4.53 bpc 1650/235 = 7.02 bpc 533( 3668) 56 | 6.( 3886) 927/237 = 3.91 bpc 4549/624 = 7.29 bpc 1394( 9362) 57 | 7.( 9895) 2512/621 = 4.05 bpc 9202/1334 = 6.90 bpc 3349( 21609) 58 | 8.( 23003) 5424/1489 = 3.64 bpc 17931/2677 = 6.70 bpc 7515( 46358) 59 | 9.( 49707) 10719/2998 = 3.58 bpc 33035/5101 = 6.48 bpc 15614( 93461) 60 | 10.( 100976) 20709/5739 = 3.61 bpc 68089/10551 = 6.45 bpc 31904( 189774) 61 | 11.( 205388) 45154/12562 = 3.59 bpc 11602/2519 = 4.61 bpc 46985( 0) 62 | Total: 63 | 147206/23189 = 3.62 bpc 86170/23189 = 6.35 bpc 46985 64 | 65 | The following example uses functions from Wavelet and Quality Assessment Toolboxes. It demonstrates that using the pdf-optimised reconstruction of quantised wavelet coefficients a meagre improvement of ~0.02 dB can be expected on high bit-rates. Functions used are **dead_zone_q** and **pdf_opt**: 66 | 67 | >> D=dwt_dyadic_decomp('Lena256.png','CDF_9x7',6); 68 | >> qstep = 4; %quantisation step is 4 69 | >> Dq = dead_zone_q(D,qstep); 70 | >> Dq_opt = pdf_opt(Dq,qstep); 71 | >> iq_measures(idwt_dyadic_recon(Dq,'CDF_9x7',6),'Lena256.png',1,1); 72 | MSE (Mean Squared Error)= 2.556086 73 | PSNR (Peak SNR)= 44.055048 dB 74 | >> iq_measures(idwt_dyadic_recon(Dq_opt,'CDF_9x7',6),'Lena256.png','disp'); 75 | MSE (Mean Squared Error)= 2.544909 76 | PSNR (Peak SNR)= 44.074081 dB 77 | 78 | DOS SPIHT binaries using function **spspiht**: 79 | 80 | >> [Arec,bitstream,PSNR]=spspiht('Lena512.png',[0.1 1],'fast'); 81 | Number of bits = 262160(32770 bytes, 1.0001 bpp) 82 | 83 | 1. bitrate - 0.1000 bpp 84 | MSE (Mean Squared Error)= 67.644821 85 | PSNR (Peak SNR)= 29.828458 dB 86 | 87 | 2. bitrate - 1.0000 bpp 88 | MSE (Mean Squared Error)= 6.532291 89 | PSNR (Peak SNR)= 39.980148 dB 90 | 91 | Total execution time - 0.84 seconds 92 | 93 | EZW (Embedded Zerotree Wavelet) algorithm with function **ezw**: 94 | 95 | >> ezw('ezw_testdata1.mat',2,2,'CDF_9x7'); 96 | Image ezw_testdata1.mat, 2 decompositions, CDF9_7 wavelet, bitrate 2.000000 bpp 97 | 98 | Example matrix: 99 | 55 42 24 -28 6 16 0 3 1 8 1 8 100 | 31 48 22 29 2 6 0 2 -8 2 -8 2 101 | 25 -21 26 20 6 18 2 7 -9 4 -9 4 102 | 1 0 29 18 16 10 5 3 1 2 1 2 103 | 17 2 7 -16 6 3 -4 6 1 0 7 0 104 | 13 -9 16 15 1 7 7 9 7 0 7 0 105 | -18 0 1 2 6 -3 5 5 -7 8 -7 8 106 | 10 2 0 8 -1 9 5 9 6 3 6 3 107 | 108 | 1. pass 109 | p z z z z z t t t t t t t t t t t t t t t t t t 110 | 1 111 | 2. pass 112 | z p z z z z t t t t t t p t t t t t t t t t t t t t t t 113 | 100 114 | 3. pass 115 | z z z z p z z t t z t t z n t z t t p t t t t t n p p t t p t t t n t t t t t t t t 116 | EZW algorithm executed in 0.047000 seconds 117 | 118 | Number of output bits: 192 119 | MSE (Mean Squared Error)= 60.529236 120 | PSNR (Peak SNR)= 30.311152 dB 121 | -------------------------------------------------------------------------------- /ZerotreeCoding/SPIHT_flowchart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsprljan/ImageCodingResearchTools/65a8ca77da7455ecfb94102a0ef8735479fc28dc/ZerotreeCoding/SPIHT_flowchart.png -------------------------------------------------------------------------------- /ZerotreeCoding/dead_zone_q.m: -------------------------------------------------------------------------------- 1 | function Y=dead_zone_q(X,qstep) 2 | %x = dead_zone_q(x,qstep) 3 | %Quantisation with a dead-zone around zero 4 | % 5 | %Input: 6 | % X - original matrix 7 | % qstep - quantisation step (threshold) 8 | % 9 | %Output: 10 | % Y - quantised matrix 11 | % 12 | %Note: 13 | % Dead zone is equal to the quantisation step, i.e. all coefficients whose 14 | % absolute value is size(optc,1) %to prevent errors when pass==1 53 | optc=optc.'; 54 | end; 55 | if ~isempty(In_halfquant) 56 | DIn(In_halfquant)=DIn(In_halfquant)-optc; 57 | end; 58 | if ~isempty(In_quant) 59 | DIn(In_quant)=DIn(In_quant)-biasold(ceil(log2(DInq(In_quant)))).'; 60 | end; 61 | Drec_opt=zeros(size(Drec)); 62 | In=Inx+(Iny-1).*size(Drec,1); 63 | Drec_opt(In)=sign(Drec(In)).*DIn; 64 | else 65 | Drec_opt=Drec; 66 | end; -------------------------------------------------------------------------------- /ZerotreeCoding/spspiht.m: -------------------------------------------------------------------------------- 1 | function [Arec,bitstream,PSNR]=spspiht(A,bpp,type) 2 | %[Arec,bitstream,PSNR]=spspiht(A,bpp,type) 3 | %Script for batch execution of DOS SPIHT binaries 4 | % 5 | %Input: 6 | % A - array containing the original image or its filename 7 | % bpp - vector of target decoding bitrates (bpp=bits per pixel) 8 | % type - [optional, default = ''] specifies in which mode to run SPIHT 9 | % if (type == '') arithemtic coding 10 | % if (type == 'fast') binary coding 11 | % 12 | %Output: 13 | % Arec - reconstructed image 14 | % bitstream - SPIHT output bitstream 15 | % PSNR - PSNR of the reconstructed images (for all bpps) 16 | % 17 | %Note: The required binaries have to reside in the \spihtexe directory. 18 | % This scripts deletes all the files created by the binaries. 19 | % Arec output is for the last specified bit-rate in bpp. SPIHT binaries 20 | % must be in the the folder specified with variable binpath. 21 | % 22 | %Uses: 23 | % fastcode.exe, fastdecd.exe, codetree.exe, decdtree.exe 24 | % ((c)1995, 1996 Amir Said & William A. Pearlman 25 | % http://www.cipr.rpi.edu/research/SPIHT/spiht3.html) 26 | % iq_measures.m (Quality Assessment toolbox) 27 | % 28 | %Example: 29 | % [Arec,bitstream,PSNR]=spspiht('Lena512.png',1,'fast'); 30 | % [Arec,bitstream,PSNR]=spspiht(A,[0.1 1]); 31 | 32 | if nargin==2 33 | type=''; 34 | end; 35 | scriptpath=fileparts(which(mfilename)); 36 | %%%SWITCHES%%% 37 | binpath = [scriptpath '\spihtexe']; 38 | SPIHTencfast = [binpath '\fastcode.exe']; 39 | SPIHTenc = [binpath '\codetree.exe']; 40 | SPIHTdecfast = [binpath '\fastdecd.exe']; 41 | SPIHTdec = [binpath '\decdtree.exe']; 42 | %%%%%%%%%%%%% 43 | if strcmp(type,'fast') 44 | fid = fopen(SPIHTencfast); 45 | if (fid == -1) error('SPIHT binary encoder executable not found!');end; 46 | fclose(fid); 47 | fid = fopen(SPIHTdecfast); 48 | if (fid == -1) error('SPIHT binary decoder executable not found!');end; 49 | fclose(fid); 50 | else 51 | fid = fopen(SPIHTenc); 52 | if (fid == -1) error('SPIHT encoder executable not found!');end; 53 | fclose(fid); 54 | fid = fopen(SPIHTdec); 55 | if (fid == -1) error('SPIHT decoder executable not found!');end; 56 | fclose(fid); 57 | end; 58 | SPIHTencfast=['"' SPIHTencfast '"']; 59 | SPIHTenc=['"' SPIHTenc '"']; 60 | SPIHTdecfast=['"' SPIHTdecfast '"']; 61 | SPIHTdec=['"' SPIHTdec '"']; 62 | 63 | if isstr(A) 64 | A=imread(A); 65 | else 66 | if strcmp(class(A),'double') A=uint8(round(A));end; 67 | end; 68 | s=size(A); 69 | maxbpp=max(bpp); 70 | fid=fopen('spiht.pic','w'); 71 | fwrite(fid,A(:),'uint8'); 72 | fclose(fid); 73 | if strcmp(type,'fast') 74 | naredba=[SPIHTencfast ' spiht.pic spiht.sc ' num2str(s(2)) ' ' num2str(s(1)) ' 1 ' num2str(maxbpp)]; 75 | else 76 | naredba=[SPIHTenc ' spiht.pic spiht.sc ' num2str(s(2)) ' ' num2str(s(1)) ' 1 ' num2str(maxbpp)]; 77 | end; 78 | tic; 79 | [c,w]=dos(naredba); 80 | fid=fopen('spiht.sc','r'); 81 | [bitstream,count] = fread(fid,'ubit1'); 82 | fclose(fid); 83 | fprintf('Number of bits = %d(%d bytes, %.4f bpp)\n',count,count/8,count/numel(A)); 84 | for i=1:length(bpp) 85 | if strcmp(type,'fast') 86 | naredba=[SPIHTdecfast ' -s spiht.sc despiht.pic ' num2str(bpp(i))]; 87 | else 88 | naredba=[SPIHTdec ' -s spiht.sc despiht.pic ' num2str(bpp(i))]; 89 | end; 90 | [c,w]=dos(naredba); 91 | fid=fopen('despiht.pic','r'); 92 | B=fread(fid,'uint8'); 93 | Arec=reshape(uint8(B),s(1),s(2)); 94 | fclose(fid); 95 | delete despiht.pic; 96 | fprintf('\n%d. bitrate - %.4f bpp\n',i,bpp(i)); 97 | [MSE,PSNR(i)]=iq_measures(Arec,A,'disp'); 98 | end; 99 | fprintf('\nTotal execution time - %.2f seconds\n',toc); 100 | %comment these out to disable deleteing 101 | delete spiht.pic; 102 | delete spiht.sc; -------------------------------------------------------------------------------- /setpaths.m: -------------------------------------------------------------------------------- 1 | function setpaths 2 | %setpaths 3 | %Adds subdirectories to the Matlab search path 4 | 5 | fp = fileparts(which(mfilename)); 6 | addpath([fp '\Dctlab']); 7 | addpath([fp '\Jpeg2000']); 8 | addpath([fp '\JSCCImage']); 9 | addpath([fp '\QualityAssessment']); 10 | addpath([fp '\Wavelet']); 11 | addpath([fp '\YUV']); 12 | addpath([fp '\ZerotreeCoding']); 13 | --------------------------------------------------------------------------------