• 基于小波变换编码的纹理图像分割


    目录

    1.算法概述

    2.仿真效果预览

    3.MATLAB部分代码预览

    4.完整MATLAB程序


    1.算法概述

          我们使用11或13维特征向量表示图像中的每个像素。两个特征用于表示像素之间的空间关系;由图像尺寸规格化的x和y像素坐标。对于灰度图像,一个特征是低通表示,它捕获平均图像强度。(低通r、g和b平面用于彩色图像)。我们使用8个特征来表示纹理信息,使用对一组定向过滤器的响应。最后,利用主成分分析法对特征空间进行降维。详细说明如下。

    二、a、 平均灰度(和颜色信息)

           我们使用中值滤波从图像中提取平均灰度和颜色信息。我们使用了一个11像素宽的中值滤波器,因为它充分抑制了小尺度纹理信息,同时仍能很好地保留轮廓和边界信息。对于彩色图像,我们对每个颜色平面应用中值过滤器。图2a和2b显示了使用的低通颜色和灰度特征。

    二、b、 纹理特征提取

          为了提取纹理特征,我们考虑与人类前注意纹理识别机制进行类比[9]。该模型包括(1)与一组偶数对称线性滤波器进行卷积,然后进行半波校正,以给出一组V1简单细胞的响应建模输出,然后(2)在空间中定位的抑制,当相同或附近位置存在强响应时,会抑制弱响应,最后(3)纹理边界检测。

          我们使用高斯差分(DOG)和偏移高斯差分滤波器(DOOG)作为线性滤波器。使用的DOG过滤器对斑点区域和使用的DOOG过滤器作出响应,对不同方向的障碍区域作出响应。我们使用两种不同的DOG滤波器来检测两个不同的斑点区域和6个不同的方向DOOG过滤器的数量。过滤器如图3所示。纹理图像对单个过滤器的响应如图4所示。请注意,与其他纹理分割方法不同,我们只使用单个尺度的过滤器(8像素宽)。我们这样做是因为在较高的比例下,纹理区域不会受到模糊瑕疵的影响,因此我们选择不使用这些区域进行纹理合成。在这一步之后,我们采用全波整流,而不是半波整流。半波校正用于复制纹理区域和它们的负片之间的区分。然而,在我们使用的小范围内,这种区分并不十分必要,我们更喜欢使用全波区分。

          为了复制步骤(2)和(3),我们不使用抑制和纹理边界检测,而是使用一个简单的9像素宽中值滤波器。众所周知,中值滤波器在强响应存在时抑制弱响应,并且仍然保持边界信息。因此,中值滤波器在一个步骤中实现了步骤(2)和(3)。

           我们基于以下对细分的洞察力进行研究。考虑图6a所示的图像及其纹理特征(使用斑点过滤器),如图6b所示。我们可以直观地将4b分割为两个区域,有纹理和无纹理。现在考虑图6c,它显示了4b的随机抽样子集。仍然可以定义轮廓并对图像进行分割,类似于4b中的分割。在这个分割之后,如果我们考虑所有剩余的点,那么它们可以在这个初始分割的基础上被分类为有纹理的或无纹理的。根据这一见解,我们推导出以下算法。

           图像被分割成不同的条形、斑点和模糊区域后,我们应用一种简单的基于规则的启发式算法将区域分类为潜在的模糊伪影及其对应的源区域(纹理未丢失的区域)。这种启发式应该具有低错误识别的特点。作为这一过程的第一步,我们将上一节中的每个片段确定为“有纹理”和“无纹理”。

    2.仿真效果预览

    matlab2022a仿真

     

     

     

     

     

     

    3.MATLAB部分代码预览

    1. disp('Preprocessing...');tic;
    2. % Preprocess all
    3. [allfeatures, rDims, cDims, depth] = preprocfast(img);
    4. [samples,olddimensions] = size(allfeatures);
    5. gallfeatures = allfeatures;
    6. % Combine all texture features to use for later thresholding
    7. % Also save all low pass features for later adjacency processing
    8. if depth == 1
    9. texturefeature = max(allfeatures(:,4:11), [], 2);
    10. lowpassfeature = allfeatures(:,3);
    11. lowpassimage = reshape(lowpassfeature, [cDims rDims])';
    12. else
    13. texturefeature = max(allfeatures(:,6:13), [], 2);
    14. lowpassfeature = allfeatures(:,3:5);
    15. lowpassimage(:,:,1) = reshape(lowpassfeature(:,1), [cDims rDims])';
    16. lowpassimage(:,:,2) = reshape(lowpassfeature(:,2), [cDims rDims])';
    17. lowpassimage(:,:,3) = reshape(lowpassfeature(:,3), [cDims rDims])';
    18. end
    19. textures = reshape(texturefeature, [cDims rDims])';
    20. % Principle component based dimensionality reduction of all features
    21. allfeatures = pca(allfeatures, 0.05);
    22. % Choose 10% of samples randomly and save in DATASET
    23. [samples, dimensions] = size(allfeatures);
    24. % We work on ~WORKSAMPLES pixels. If the image has less we use all pixels.
    25. % If not then the appropriate portion of pixels is randomly selected.
    26. worksamples = samples/10;
    27. if worksamples < 10000
    28. worksamples = 10000;
    29. end
    30. if samples < worksamples
    31. worksamples = samples;
    32. end
    33. choose = rand([samples 1]); choose = choose < (worksamples/samples);
    34. dataset = zeros([sum(choose), dimensions]);
    35. dataset(1:sum(choose),:) = allfeatures(find(choose),:); % find(choose) returns array where choose is non zero
    36. disp('Preprocessing done.');t = toc; totalt = totalt + t;
    37. disp([' Original dimensions: ' int2str(olddimensions)]);
    38. disp([' Reduced dimensions by PCA: ' int2str(dimensions)]);
    39. disp([' Image has ' int2str(rDims * cDims) ' pixels.']);
    40. disp([' Using only ' int2str(size(dataset,1)) ' pixels.']);
    41. disp(['Elapsed time: ' num2str(t)]);
    42. disp(' ');
    43. % SEGMENTATION
    44. % 1. k-means (on sampled image)
    45. % 2. Use centroids to classify remaining points
    46. % 3. Classify spatially disconnected regions as separate regions
    47. % Segmentation Step 1.
    48. % k-means (on sampled image)
    49. % Compute k-means on randomly sampled points
    50. disp('Computing k-means...');tic;
    51. % Set number of clusters heuristically.
    52. k = round((rDims*cDims)/(100*100)); k = max(k,8); k = min(k,16);
    53. % Uncomment this line when MATLAB k-means unavailable
    54. %[centroids,esq,map] = kmeanlbg(dataset,k);
    55. [map, centroids] = kmeans(dataset, k); % Calculate k-means (use MATLAB k-mean
    56. disp('k-means done.');t = toc; totalt = totalt + t;
    57. disp([' Number of clusters: ' int2str(k)]);
    58. disp(['Elapsed time: ' num2str(t)]);
    59. disp(' ');
    60. % Segmentation Step 2.
    61. % Use centroids to classify the remaining points
    62. disp('Using centroids to classify all points...');tic;
    63. globsegimage = postproc(centroids, allfeatures, rDims, cDims); % Use centroids to classify all points
    64. % Segmentation Step 3.
    65. % Classify spatially disconnected regions as separate regions
    66. globsegimage = medfilt2(globsegimage, [3 3], 'symmetric');
    67. globsegimage = imfill(globsegimage);
    68. region_count = max(max(globsegimage));
    69. count = 1; newglobsegimage = zeros(size(globsegimage));
    70. for i = 1:region_count
    71. region = (globsegimage == i);
    72. [bw, num] = bwlabel(region);
    73. for j = 1:num
    74. newglobsegimage = newglobsegimage + count*(bw == j);
    75. count = count + 1;
    76. end
    77. end
    78. oldglobsegimage = globsegimage;
    79. globsegimage = newglobsegimage;
    80. disp('Classification done.');t = toc; totalt = totalt + t;
    81. disp(['Elapsed time: ' num2str(t)]);
    82. disp(' ');
    83. % DISPLAY IMAGES
    84. % Display segments
    85. %figure(1), imshow(globsegimage./max(max(globsegimage)));
    86. figure(1), imshow(label2rgb(globsegimage, 'gray'));
    87. title('Segments');
    88. % Calculate boundary of segments
    89. BW = edge(globsegimage,'sobel', 0);
    90. % Superimpose boundary on original image
    91. iout = img;
    92. if (depth == 1) % Gray image, so use color lines
    93. iout(:,:,1) = iout;
    94. iout(:,:,2) = iout(:,:,1);
    95. iout(:,:,3) = iout(:,:,1);
    96. iout(:,:,2) = min(iout(:,:,2) + BW, 1.0);
    97. iout(:,:,3) = min(iout(:,:,3) + BW, 1.0);
    98. else % RGB image, so use white lines
    99. iout(:,:,1) = min(iout(:,:,1) + BW, 1.0);
    100. iout(:,:,2) = min(iout(:,:,2) + BW, 1.0);
    101. iout(:,:,3) = min(iout(:,:,3) + BW, 1.0);
    102. end
    103. % Display image and segments
    104. figure(2), imshow(iout);
    105. title('Segmented image');
    106. % POST PROCESSING AND AUTOMATIC SELECTION OF SOURCE AND TARGET REGIONS
    107. % 1. Find overall textured region using Otsu's method (MATLAB graythresh)
    108. % 2. Save each region and region boundary separately and note index of
    109. % textured regions
    110. % 3. For each textured region, find all adjacent untextured regions and
    111. % save in adjacency matrix. Regions having a significant common border
    112. % are considered adjacent.
    113. % 4. Find similarity between textured and adjacent untextured regions
    114. % using average gray level matching (average color matching). For each
    115. % textured region, drop those adjacent regions which don't match in
    116. % gray level.
    117. disp('Post-processing and automatically selecting source and target regions...');tic;
    118. % POSTPROC Step 1
    119. threshold = graythresh(rescalegray(textures));
    120. bwtexture = textures > threshold;
    121. tex_edges = edge(bwtexture, 'sobel', 0);
    122. figure(3),
    123. if depth == 1
    124. imshow(min(img + tex_edges, 1));
    125. else
    126. imshow(min(img + cat(3, tex_edges, tex_edges, tex_edges), 1));
    127. end
    128. title('Textured regions');
    129. % POSTPROC Step 2
    130. % Save each region in a dimension
    131. % Save each region boundary in a dimension
    132. % For each region which can be classified as a textured region store index
    133. region_count = max(max(globsegimage));
    134. number_tex_regions = 1; tex_list = [];
    135. for region_number = 1:region_count
    136. bwregion = (globsegimage == region_number);
    137. regions(:,:,region_number) = bwregion; % Save all regions
    138. region_boundaries(:,:,region_number) = edge(bwregion, 'sobel', 0);
    139. if ( (sum(sum(bwregion.*bwtexture))/sum(sum(bwregion)) > 0.75) && sum(sum(bwregion)) > (32*32) )
    140. tex_list = [tex_list region_number];
    141. number_tex_regions = number_tex_regions + 1;
    142. end
    143. end
    144. number_tex_regions = number_tex_regions - 1;
    145. % POSTPROC Step 3
    146. % Find texture region adjacency and create an adjacency matrix
    147. for i = 1:size(tex_list, 2)
    148. for j = 1:region_count
    149. if (tex_list(i) ~= j)
    150. boundary_overlap = sum(sum( region_boundaries(:,:,tex_list(i)).*region_boundaries(:,:,j) ));
    151. boundary_total_length = sum(sum( region_boundaries(:,:,tex_list(i)))) + sum(sum(region_boundaries(:,:,j)));
    152. if (boundary_overlap/boundary_total_length > 0) % If overlap is at least 20% of total boundary length
    153. region_adjacency(i,j) = boundary_overlap; % accept it as a boundary
    154. end
    155. end
    156. end
    157. end
    158. % EXPERIMENTAL
    159. region_adj_hard_coded = (region_adjacency - 0.2*repmat(mean(region_adjacency,2), [1 size(region_adjacency,2)])) > 0;
    160. % Copy adjacency into another variable and remove all references to
    161. % textured regions from the adjacency matrix.
    162. region_output = region_adj_hard_coded;
    163. for tex_count = 1:size(tex_list, 2)
    164. region_output(:,tex_list(tex_count)) = 0;
    165. end
    166. % POSTPROC Step 4
    167. % Find similarity between textured and adjacent untextured regions
    168. % (This could be changed to a chi-squared distance between histograms of
    169. % textLP and adjacent by commenting out required code, and uncommenting
    170. % other code, as directed in the source)
    171. % For all textured regions find and save average brightness
    172. for tex_count = 1:size(tex_list, 2)
    173. if depth == 1
    174. tex_avg_bright(tex_count) = sum(sum(regions(:,:,tex_list(tex_count)).*lowpassimage)) ...
    175. / sum(sum(regions(:,:,tex_list(tex_count))));
    176. % Comment previous and uncomment next line(s) to use histogram
    177. % processing
    178. %tex_hist{tex_count} = histproc(regions(:,:,tex_list(tex_count)), lowpassimage);
    179. else
    180. tex_avg_bright(1,tex_count) = sum(sum(regions(:,:,tex_list(tex_count)).*lowpassimage(:,:,1))) ...
    181. / sum(sum(regions(:,:,tex_list(tex_count))));
    182. tex_avg_bright(2,tex_count) = sum(sum(regions(:,:,tex_list(tex_count)).*lowpassimage(:,:,2))) ...
    183. / sum(sum(regions(:,:,tex_list(tex_count))));
    184. tex_avg_bright(3,tex_count) = sum(sum(regions(:,:,tex_list(tex_count)).*lowpassimage(:,:,3))) ...
    185. / sum(sum(regions(:,:,tex_list(tex_count))));
    186. % Comment previous and uncomment next line(s) to use histogram
    187. % processing
    188. % tex_hist{tex_count} = histproc(regions(:,:,tex_list(tex_count)), lowpassimage);
    189. end
    190. end
    191. % For all textured regions, consider each non-textured region and update
    192. % adjacency matrix. Keep the relationship if gray levels (colors) are similar and
    193. % drop if the gray levels (colors) don't match.
    194. for tex_count = 1:size(tex_list, 2) % For all textured regions
    195. for adj_reg_count = 1:size(region_adj_hard_coded, 2)
    196. if (region_adj_hard_coded(tex_count, adj_reg_count) > 0)
    197. if depth == 1
    198. region_avg_bright = sum(sum(regions(:,:,adj_reg_count).*lowpassimage)) ...
    199. / sum(sum(regions(:,:,adj_reg_count)));
    200. % Comment previous and uncomment next line(s) to use histogram
    201. % processing
    202. % region_hist = histproc(regions(:,:,adj_reg_count), lowpassimage);
    203. else
    204. region_avg_bright(1) = sum(sum(regions(:,:,adj_reg_count).*lowpassimage(:,:,1))) ...
    205. / sum(sum(regions(:,:,adj_reg_count)));
    206. region_avg_bright(2) = sum(sum(regions(:,:,adj_reg_count).*lowpassimage(:,:,2))) ...
    207. / sum(sum(regions(:,:,adj_reg_count)));
    208. region_avg_bright(3) = sum(sum(regions(:,:,adj_reg_count).*lowpassimage(:,:,3))) ...
    209. / sum(sum(regions(:,:,adj_reg_count)));
    210. % Comment previous and uncomment next line(s) to use histogram
    211. % processing
    212. % region_hist = histproc(regions(:,:,adj_reg_count), lowpassimage);
    213. end
    214. if depth == 1
    215. if abs(tex_avg_bright(tex_count) - region_avg_bright) > 0.2 % Highly similar
    216. region_output(tex_count, adj_reg_count) = 0;
    217. end
    218. % Comment previous and uncomment next line(s) to use histogram
    219. % processing
    220. % if chisq(tex_hist{tex_count}, region_hist) > 0.4
    221. % chisq(tex_hist{tex_count}, region_hist)
    222. % region_output(tex_count, adj_reg_count) = 0;
    223. % end
    224. else
    225. if mean(abs(tex_avg_bright(:,tex_count) - region_avg_bright')) > 0.2
    226. region_output(tex_count, adj_reg_count) = 0;
    227. end
    228. % Comment previous and uncomment next line(s) to use histogram
    229. % processing
    230. % thist = tex_hist{tex_count};
    231. % chisq(thist(:,1),region_hist(:,1))
    232. % chisq(thist(:,2),region_hist(:,2))
    233. % chisq(thist(:,3),region_hist(:,3))
    234. % t = 0.9;
    235. % if (chisq(thist(:,1),region_hist(:,1)) > t) || ...
    236. % (chisq(thist(:,2),region_hist(:,2)) > t) || ...
    237. % (chisq(thist(:,3),region_hist(:,3)) > t)
    238. % region_output(tex_count, adj_reg_count) = 0;
    239. % end
    240. end
    241. end
    242. end
    243. end
    244. disp('Post-processing done.'); t = toc; totalt = totalt + t;
    245. disp(['Elapsed time: ' num2str(t)]);
    246. disp(' ');
    247. disp(['Total time elapsed: ' int2str(floor(totalt/60)) ' minutes ' int2str(mod(totalt,60)) ' seconds.']);
    248. % DISPLAY IMAGES
    249. % Display source and target regions.
    250. if depth == 1
    251. imgs = zeros([rDims cDims size(tex_list,2)]);
    252. for tex_count = 1:size(tex_list, 2)
    253. if (sum(region_output(tex_count,:) > 0)) % If we have target patches
    254. imgs(:,:,tex_count) = regions(:,:,tex_list(tex_count)).*img; % Save that source patch
    255. for i = 1:size(region_output, 2) % For each region
    256. if (region_output(tex_count, i) > 0) % which is connected to that source patch
    257. imgs(:,:,tex_count) = imgs(:,:,tex_count) + 0.5*regions(:,:,i).*img; % Save the target patch
    258. end
    259. end
    260. figure, imshow(min(imgs(:,:,tex_count) + BW, 1));
    261. ggg{tex_count} = min(imgs(:,:,tex_count) + BW, 1);
    262. title('Potential source and target regions');
    263. end
    264. end
    265. else % depth == 3
    266. count = 1;
    267. for tex_count = 1:size(tex_list, 2)
    268. if (sum(region_output(tex_count,:) > 0)) % If we have target patches
    269. tmp(:,:,1) = regions(:,:,tex_list(tex_count)).*img(:,:,1);
    270. tmp(:,:,2) = regions(:,:,tex_list(tex_count)).*img(:,:,2);
    271. tmp(:,:,3) = regions(:,:,tex_list(tex_count)).*img(:,:,3);
    272. imgs{count} = tmp;
    273. for i = 1:size(region_output, 2) % For each region
    274. if (region_output(tex_count, i) > 0) % which is connected to that source patch
    275. tmp(:,:,1) = 0.5*regions(:,:,i).*img(:,:,1);
    276. tmp(:,:,2) = 0.5*regions(:,:,i).*img(:,:,2);
    277. tmp(:,:,3) = 0.5*regions(:,:,i).*img(:,:,3);
    278. imgs{count} = imgs{count} + tmp;
    279. end
    280. end
    281. figure, imshow(min(imgs{count} + cat(3,BW,BW,BW), 1));
    282. ggg{count} = min(imgs{count} + cat(3,BW,BW,BW), 1);
    283. title('Potential source and target regions');
    284. count = count+1;
    285. end
    286. end
    287. end
    288. A11

    4.完整MATLAB程序

    matlab源码说明_我爱C编程的博客-CSDN博客

    V

  • 相关阅读:
    组件分享之后端组件——基于Golang实现的database/sql附加功能组件dbr
    十一、一起学习Lua 迭代器
    释放潜力:人工智能对个性化学习的影响
    logstash使用参考
    pytorch笔记 GRUCELL
    java+springboot基于微信小程序的在线办公系统 uniapp 小程序
    带你认识图数据库性能和场景测试利器LDBC SNB
    WindowManagerService详述
    generated-requests.http
    《Linux运维实战:基于银河麒麟V10+鲲鹏920CPU部署DM8数据库主备集群》
  • 原文地址:https://blog.csdn.net/hlayumi1234567/article/details/127948949