CPBD_compute.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. %=====================================================================
  2. % File: CPBD_compute.m
  3. % Original code written by Niranjan D. Narvekar
  4. % IVU Lab (http://ivulab.asu.edu)
  5. % Last Revised: October 2009 by Niranjan D. Narvekar
  6. %=====================================================================
  7. % Copyright Notice:
  8. % Copyright (c) 2009-2010 Arizona Board of Regents.
  9. % All Rights Reserved.
  10. % Contact: Lina Karam (karam@asu.edu) and Niranjan D. Narvekar (nnarveka@asu.edu)
  11. % Image, Video, and Usabilty (IVU) Lab, ivulab.asu.edu
  12. % Arizona State University
  13. % This copyright statement may not be removed from this file or from
  14. % modifications to this file.
  15. % This copyright notice must also be included in any file or product
  16. % that is derived from this source file.
  17. %
  18. % Redistribution and use of this code in source and binary forms,
  19. % with or without modification, are permitted provided that the
  20. % following conditions are met:
  21. % - Redistribution's of source code must retain the above copyright
  22. % notice, this list of conditions and the following disclaimer.
  23. % - Redistribution's in binary form must reproduce the above copyright
  24. % notice, this list of conditions and the following disclaimer in the
  25. % documentation and/or other materials provided with the distribution.
  26. % - The Image, Video, and Usability Laboratory (IVU Lab,
  27. % http://ivulab.asu.edu) is acknowledged in any publication that
  28. % reports research results using this code, copies of this code, or
  29. % modifications of this code.
  30. % The code and our papers are to be cited in the bibliography as:
  31. %
  32. % The code and our papers are to be cited in the bibliography as:
  33. %
  34. % N.D. Narvekar and L. J. Karam, "CPBD Sharpness Metric Software",
  35. % http://ivulab.asu.edu/Quality/CPBD
  36. %
  37. % N.D. Narvekar and L. J. Karam, "A No-Reference Perceptual Image Sharpness
  38. % Metric Based on a Cumulative Probability of Blur Detection,"
  39. % International Workshop on Quality of Multimedia Experience (QoMEX 2009),
  40. % pp. 87-91, July 2009.
  41. %
  42. % N. D. Narvekar and L. J. Karam, "An Improved No-Reference Sharpness Metric Based on the
  43. % Probability of Blur Detection," International Workshop on Video Processing and Quality Metrics
  44. % for Consumer Electronics (VPQM), http://www.vpqm.org, January 2010.
  45. %
  46. % DISCLAIMER:
  47. % This software is provided by the copyright holders and contributors
  48. % "as is" and any express or implied warranties, including, but not
  49. % limited to, the implied warranties of merchantability and fitness for
  50. % a particular purpose are disclaimed. In no event shall the Arizona
  51. % Board of Regents, Arizona State University, IVU Lab members, or
  52. % contributors be liable for any direct, indirect, incidental, special,
  53. % exemplary, or consequential damages (including, but not limited to,
  54. % procurement of substitute goods or services; loss of use, data, or
  55. % profits; or business interruption) however caused and on any theory
  56. % of liability, whether in contract, strict liability, or tort
  57. % (including negligence or otherwise) arising in any way out of the use
  58. % of this software, even if advised of the possibility of such damage.
  59. %
  60. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  61. % function : CPBD_compute
  62. % description : This function computes the CPBD metric which determines
  63. % the amount of sharpness of the image. Larger the metric
  64. % value, sharper the image.
  65. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  66. function [sharpness_metric] = CPBD_compute(input_image)
  67. %%%%%%%%%%%% pre-processing %%%%%%%%%%%%
  68. % convert to gray scale if color image
  69. [x y z] = size(input_image);
  70. if z > 1
  71. input_image = rgb2gray(input_image);
  72. end
  73. % convert the image to double for further processing
  74. input_image = double(input_image);
  75. % get the size of image
  76. [m,n] = size(input_image);
  77. %%%%%%%%%%%% parameters %%%%%%%%%%%%
  78. % threshold to characterize blocks as edge/non-edge blocks
  79. threshold = 0.002;
  80. % fitting parameter
  81. beta = 3.6;
  82. % block size
  83. rb = 64;
  84. rc = 64;
  85. % maximum block indices
  86. max_blk_row_idx = floor(m/rb);
  87. max_blk_col_idx = floor(n/rc);
  88. % just noticeable widths based on the perceptual experiments
  89. %widthjnb = [5*ones(1,57) 3*ones(1,200)];
  90. widthjnb = [5*ones(1,51) 3*ones(1,205)];
  91. %%%%%%%%%%%% initialization %%%%%%%%%%%%
  92. % arrays and variables used during the calculations
  93. total_num_edges = 0;
  94. hist_pblur = zeros(1,101);
  95. cum_hist = zeros(1,101);
  96. %%%%%%%%%%%% edge detection %%%%%%%%%%%%
  97. % edge detection using canny and sobel canny edge detection is done to
  98. % classify the blocks as edge or non-edge blocks and sobel edge
  99. % detection is done for the purpose of edge width measurement.
  100. input_image_canny_edge = edge(input_image,'canny');
  101. input_image_sobel_edge = edge(input_image,'Sobel',[2],'vertical');
  102. %%%%%%%%%%%% edge width calculation %%%%%%%%%%%%
  103. [width] = marziliano_method(input_image_sobel_edge, input_image);
  104. %%%%%%%%%%%% sharpness metric calculation %%%%%%%%%%%%
  105. % loop over the blocks
  106. for i=1:max_blk_row_idx
  107. for j=1:max_blk_col_idx
  108. % get the row and col indices for the block pixel positions
  109. rows = (rb*(i-1)+1):(rb*i);
  110. cols = (rc*(j-1)+1):(rc*j);
  111. % decide whether the block is an edge block or not
  112. decision = get_edge_blk_decision(input_image_canny_edge(rows,cols), threshold);
  113. % process the edge blocks
  114. if (decision==1)
  115. % get the edge widths of the detected edges for the block
  116. local_width = width(rows,cols);
  117. local_width = local_width(local_width ~= 0);
  118. % find the contrast for the block
  119. blk_contrast = blkproc(double(input_image(rows,cols)),[rb rc],@get_contrast_block)+1;
  120. % get the block Wjnb based on block contrast
  121. blk_jnb = widthjnb(blk_contrast);
  122. % calculate the probability of blur detection at the edges
  123. % detected in the block
  124. prob_blur_detection = 1 - exp(-abs(local_width./blk_jnb).^beta);
  125. % update the statistics using the block information
  126. for k = 1:numel(local_width)
  127. % update the histogram
  128. temp_index = round(prob_blur_detection(k)* 100) + 1;
  129. hist_pblur(temp_index) = hist_pblur(temp_index) + 1;
  130. % update the total number of edges detected
  131. total_num_edges = total_num_edges + 1;
  132. end
  133. end
  134. end
  135. end
  136. % normalize the pdf
  137. if(total_num_edges ~=0)
  138. hist_pblur = hist_pblur / total_num_edges;
  139. else
  140. hist_pblur = zeros(size(hist_pblur));
  141. end
  142. % calculate the sharpness metric
  143. sharpness_metric = sum(hist_pblur(1:64));
  144. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  145. % function : marziliano_method
  146. % description : This function calculates the edge-widths of the detected
  147. % edges and returns an matrix as big as the image with 0's
  148. % at non-edge locations and edge-widths at the edge
  149. % locations.
  150. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  151. function [edge_width_map] = marziliano_method(E, A)
  152. % edge_width_map consists of zero and non-zero values. A zero value
  153. % indicates that there is no edge at that position and a non-zero value
  154. % indicates that there is an edge at that position and the value itself
  155. % gives the edge width
  156. edge_width_map = zeros(size(A));
  157. % converting the image to type double
  158. A = double(A);
  159. % find the gradient for the image
  160. [Gx Gy] = gradient(A);
  161. % dimensions of the image
  162. [M N] = size(A);
  163. % initializing the matrix to empty which holds the angle information of the
  164. % edges
  165. angle_A = [];
  166. % calculate the angle of the edges
  167. for m=1:M
  168. for n=1:N
  169. if (Gx(m,n)~=0)
  170. angle_A(m,n) = atan2(Gy(m,n),Gx(m,n))*(180/pi); % in degrees
  171. end
  172. if (Gx(m,n)==0 && Gy(m,n)==0)
  173. angle_A(m,n) = 0;
  174. end
  175. if (Gx(m,n)==0 && Gy(m,n)==pi/2)
  176. angle_A(m,n) = 90;
  177. end
  178. end
  179. end
  180. if(numel(angle_A) ~= 0)
  181. % quantize the angle
  182. angle_Arnd = 45*round(angle_A./45);
  183. count = 0;
  184. for m=2:M-1
  185. for n=2:N-1
  186. if (E(m,n)==1)
  187. %%%%%%%%%%%%%%%%%%%% If gradient angle = 180 or -180 %%%%%%%%%%%%%%%%%%%%%%
  188. if (angle_Arnd(m,n) ==180 || angle_Arnd(m,n) ==-180)
  189. count = count + 1;
  190. for k=0:100
  191. posy1 = n-1 -k;
  192. posy2 = n-2 -k;
  193. if ( posy2<=0)
  194. break;
  195. end
  196. if ((A(m,posy2) - A(m,posy1))<=0)
  197. break;
  198. end
  199. end
  200. width_count_side1 = k + 1 ;
  201. for k=0:100
  202. negy1 = n+1 + k;
  203. negy2 = n+2 + k;
  204. if (negy2>N)
  205. break;
  206. end
  207. if ((A(m,negy2) - A(m,negy1))>=0)
  208. break;
  209. end
  210. end
  211. width_count_side2 = k + 1 ;
  212. edge_width_map(m,n) = width_count_side1+width_count_side2;
  213. end
  214. %%%%%%%%%%%%%%%%%%%% If gradient angle = 0 %%%%%%%%%%%%%%%%%%%%%%
  215. if (angle_Arnd(m,n) ==0)
  216. count = count + 1;
  217. for k=0:100
  218. posy1 = n+1 +k;
  219. posy2 = n+2 +k;
  220. if ( posy2>N)
  221. break;
  222. end
  223. if ((A(m,posy2) - A(m,posy1))<=0)
  224. break;
  225. end
  226. end
  227. width_count_side1 = k + 1 ;
  228. for k=0:100
  229. negy1 = n-1 - k;
  230. negy2 = n-2 - k;
  231. if (negy2<=0)
  232. break;
  233. end
  234. if ((A(m,negy2) - A(m,negy1))>=0)
  235. break;
  236. end
  237. end
  238. width_count_side2 = k + 1 ;
  239. edge_width_map(m,n) = width_count_side1+width_count_side2;
  240. end
  241. end
  242. end
  243. end
  244. end
  245. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  246. % function : get_edge_blk_decision
  247. % description : Gives a decision whether the block is edge block or not.
  248. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  249. function [im_out] = get_edge_blk_decision(im_in,T)
  250. [m,n] = size(im_in);
  251. L = m*n;
  252. im_edge_pixels = sum(sum(im_in));
  253. im_out = im_edge_pixels > (L*T) ;
  254. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  255. % function : get_contrast_block
  256. % description : Returns the contrast of the block.
  257. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  258. function contrast = get_contrast_block(A)
  259. A = double(A);
  260. [m,n] =size(A);
  261. % get constrast locally
  262. contrast = max(max(A)) - min(min(A));