• 基于MSER的高速公路交通标志提取matlab仿真


    目录

    1.算法描述

    2.仿真效果预览

    3.MATLAB核心程序

    4.完整MATLAB


    1.算法描述

           自然场景下的文本检测是自然场景图像信息提取的基础,在车牌识别、实时翻译、图像检索等领域具有广泛的应用价值及研究意义。基于连通区域的方法是自然场景文本检测中最为常见的方法,其中最大稳定极值区域(Maximally Stable Extremal Regions,MSER)算法和颜色聚类算法都有着广泛的应用。

    MSER = Maximally Stable Extremal Regions
    最大极值稳定区
    业界认为是性能最好的仿射不变区域,MSER是当使用不同的灰度阈值对图像进行二值化时得到的最稳定的区域,特点:
    1.对于图像灰度的仿射变化具有不变性
    2.稳定性,区域的支持集相对灰度变化稳定
    3.可以检测不同精细程度的区域

           交通标志检测和识别系统的关键在于交通标志候选区域的分割、交通标志的特征提取和分类器的设计。交通标志背景复杂,很难从其背景中将其分割出来,并且由于交通标志一般放在户外场景中,受外界原因(光照,损坏、遮挡等)影响较大,这就大大加大了交通标志检测的难度。交通标志本身种类繁多,相同形状的交通标志根据其象形图案的不同,意义千差万别,造成识别阶段准确率低。

           交通标志路牌中的每个交通标志信息均可以用一个区域特征来表示,最大稳定极值区域(Maximally Stable Extremal Regions,简称 MSER)就是一种很好的区域检测算子,它是由 Matas等人]提出的一种局部区域仿射不变特征的区域检查算子。该算子已用于大规模图像索、识别、以及跟踪,相比其他区域算子,该算子对图像灰度具有仿射变换不变性和多尺度检测目标的优点,能够很好的提取交通标志有效区域,有助于交通标志的定位及分割。MSER算法中,其极值区域的定义为和图像的阈值相关,设定好灰度阈值后,在图像中的某个区域能够成为极值区域的条件是无法再找到一个不大于所设定的灰度阈值的像素点去扩大当前区域。在所有的二值化图中,每个连通区域都是一个极值区域,即使是一个黑点,也是一个极值区域。任选两个极值区域,只有两种关系,一种是没有交集,一种是包含。每个二值图像上可以有多个极值区域,原始灰度图像中每个像素点可能对应多个二值图像上的极值区域。

          MSER算法中,其最大稳定极值区域的定义为极值区域随着设置的灰度阈值的增大而逐渐“长大”。这样的一组极值区域由小到大是相互嵌套的关系,分别用来表示这一系列相互嵌套的极值区域序列。如果为MSER,则其满足如下条件:

     

       变量表示的是像素差值。由于 Q 是一个像素点的集合,所以绝对值代表的是该集合的基数,表示这个极值区域的面积。需先要先找到所有的极值区域,然后通过上面的“稳定标准”来确定最终的 MSER。

    MSER = Maximally Stable Extremal Regions

    业界认为是性能最好的仿射不变区域,MSER是当使用不同的灰度阈值对图像进行二值化时得到的最稳定的区域,特点:

    1.对于图像灰度的仿射变化具有不变性

    2.稳定性,区域的支持集相对灰度变化稳定

    3.可以检测不同精细程度的区域

    MSER提取过程

    1.使用一系列灰度阈值对图像进行二值化处理

    2.对于每个阈值得到的二值图像,得到相应的黑色区域与白色区域

    3.在比较宽的灰度阈值范围内保持形状稳定的区域就是MSERs

    4.评判标准: dA/dt

    A: 二值图像区域面积,t: 灰度阈值

    2.仿真效果预览

    matlab2022a仿真如下:

     

     

    3.MATLAB核心程序

    1. % 1) Select input image to process if it's gray or segmented and create a single
    2. % row vector with the image
    3. switch usage
    4. case 'segmented'
    5. % Simple segmentation by color threshold
    6. img_seg = f_seg(img, color_threshold, color_of_interest, ratio);
    7. subplot(2,2,1);
    8. imshow(img);
    9. title(['Original Image (' num2str(width) 'x' num2str(height) ')']);
    10. subplot(2,2,2);
    11. imshow(img_seg);
    12. title(['Segmented img ( Color filt:' color_of_interest ' Threshold:' ...
    13. num2str(color_threshold) ')']);
    14. i = 1;
    15. for y=1:height
    16. for x=1:width
    17. if img_seg(y,x) == 0
    18. img_scan(i,1) = 1;
    19. else
    20. img_scan(i,1) = img_seg(y,x);
    21. end
    22. i=i+1;
    23. end
    24. end
    25. img_selected = img_seg;
    26. case 'gray'
    27. % Image converted in gray scale
    28. img_grey = rgb2gray(img);
    29. subplot(2,2,1);
    30. imshow(img);
    31. title(['Original Image (' num2str(width) 'x' num2str(height) ')']);
    32. subplot(2,2,2);
    33. imshow(img_grey);
    34. title(['Gray Image (' num2str(size(img_grey,2)) 'x' ...
    35. num2str(size(img_grey,1)) ')']);
    36. i = 1;
    37. for y=1:height
    38. for x=1:width
    39. if img_grey(y,x) == 0
    40. img_scan(i,1) = 1;
    41. else
    42. img_scan(i,1) = img_grey(y,x);
    43. end
    44. i=i+1;
    45. end
    46. end
    47. img_selected = img_grey;
    48. end
    49. % 2) Create the bin mask with accessed pixels
    50. bin_mask_access = zeros(total_pixels_img,1);
    51. % 3) Initialize control variables
    52. priority = 256; % Variable that defines the smallest
    53. % 'dark' pixel
    54. current_pixel = 1;
    55. current_edge = 0;
    56. current_level = img_scan(current_pixel);
    57. bin_mask_access(current_pixel) = 1;
    58. index_regions = 0;
    59. g_index_stack = 0;
    60. % Create the LIFO for the 256 gray leves
    61. for i=1:256
    62. boundary_pixels(i) = CStack();
    63. end
    64. % Insert into the tree the most 'bright' pixel that equivalent to 256
    65. g_index_stack = g_index_stack + 1;
    66. index_regions = index_regions + 1;
    67. region_stack(index_regions).level = 256;
    68. region_stack(index_regions).area = 0;
    69. region_stack(index_regions).mom(1) = 0;
    70. region_stack(index_regions).mom(2) = 0;
    71. region_stack(index_regions).mom(3) = 0;
    72. region_stack(index_regions).mom(4) = 0;
    73. region_stack(index_regions).mom(5) = 0;
    74. region_stack(index_regions).variation_mser = 999999;
    75. region_stack(index_regions).stable = 0;
    76. region_stack(index_regions).parent = 0;
    77. region_stack(index_regions).child = 0;
    78. region_stack(index_regions).next = 0;
    79. % This is an auxiliary vector (LIFO) to store the regions pushed and not process
    80. % ed by the function 'process_stack' yet, which defines the parent and child nod
    81. % es. In normal behavior this must inflate and deinflate during the image proces
    82. % sing
    83. stack(g_index_stack).node = index_regions;
    84. % Each region_stack has a correspondent rect that represents the rectangle assoc
    85. % iated with that region, it facilitates in the later step
    86. rect(index_regions).top = Inf;
    87. rect(index_regions).bottom = 0;
    88. rect(index_regions).left = Inf;
    89. rect(index_regions).right = 0;
    90. rect(index_regions).draw = 1;
    91. % Insert into the tree the first region for the first pixel level in the image
    92. g_index_stack = g_index_stack + 1;
    93. index_regions = index_regions + 1;
    94. region_stack(index_regions).level = current_level;
    95. region_stack(index_regions).area = 0;
    96. region_stack(index_regions).mom(1) = 0;
    97. region_stack(index_regions).mom(2) = 0;
    98. region_stack(index_regions).mom(3) = 0;
    99. region_stack(index_regions).mom(4) = 0;
    100. region_stack(index_regions).mom(5) = 0;
    101. region_stack(index_regions).variation_mser = 999999;
    102. region_stack(index_regions).stable = 0;
    103. region_stack(index_regions).parent = 0;
    104. region_stack(index_regions).child = 0;
    105. region_stack(index_regions).next = 0;
    106. stack(g_index_stack).node = index_regions;
    107. rect(index_regions).top = Inf;
    108. rect(index_regions).bottom = 0;
    109. rect(index_regions).left = Inf;
    110. rect(index_regions).right = 0;
    111. rect(index_regions).draw = 1;
    112. % 4) Run the main algorithm that will scan all pixels inside the image
    113. gCounter = 0;
    114. done = 0;
    115. while (done == 0)
    116. gCounter = gCounter+1; % ...it'll always be the total_pixels_img
    117. % While loop to scan all edges of the pixel in analisys
    118. while current_edge < 4
    119. % ...get the neighbor pixel according to correspondent edge in the BIG row v
    120. % ector that contains all pixels
    121. neighbor_pixel = f_neighbor_pixel(current_pixel,current_edge,width,height);
    122. if (bin_mask_access(neighbor_pixel) == 0)
    123. neighbor_level = img_scan(neighbor_pixel,1);
    124. bin_mask_access(neighbor_pixel) = 1;
    125. % If the neighbor pixel has a 'lowest (black)' level than the current one,
    126. % let push a new region and define as our new current pixel
    127. if (neighbor_level < current_level)
    128. boundary_pixels(current_level).push(bitor(bitshift(current_pixel,4), ...
    129. (current_edge+1)));
    130. % ..always define priority as the 'darkest' pixel founded, because we'll
    131. % search for that pixel in the boundary stack after if we do not find an
    132. % y pixel lowest (black) in the edges
    133. if (current_level < priority)
    134. priority = current_level;
    135. end
    136. current_pixel = neighbor_pixel;
    137. current_edge = 0;
    138. current_level = neighbor_level;
    139. % Push a new region with the new 'darkest' pixel founded
    140. index_regions = index_regions + 1;
    141. region_stack(index_regions).level = current_level;
    142. region_stack(index_regions).area = 0;
    143. region_stack(index_regions).mom(1) = 0;
    144. region_stack(index_regions).mom(2) = 0;
    145. region_stack(index_regions).mom(3) = 0;
    146. region_stack(index_regions).mom(4) = 0;
    147. region_stack(index_regions).mom(5) = 0;
    148. region_stack(index_regions).variation_mser = 999999;
    149. region_stack(index_regions).stable = 0;
    150. region_stack(index_regions).parent = 0;
    151. region_stack(index_regions).child = 0;
    152. region_stack(index_regions).next = 0;
    153. g_index_stack = g_index_stack + 1;
    154. stack(g_index_stack).node = index_regions;
    155. % ..and its rectangle combined
    156. rect(index_regions).top = Inf;
    157. rect(index_regions).bottom = 0;
    158. rect(index_regions).left = Inf;
    159. rect(index_regions).right = 0;
    160. rect(index_regions).draw = 1;
    161. continue;
    162. end
    163. % If the current pixel is the 'lowest (black)', store the neighboor for la
    164. % ter search iteration
    165. boundary_pixels(neighbor_level).push(bitor(bitshift(neighbor_pixel,4),0));
    166. if (neighbor_level < priority)
    167. priority = neighbor_level;
    168. end
    169. end
    170. current_edge = current_edge + 1;
    171. end
    172. A86

    4.完整MATLAB

    V

  • 相关阅读:
    判断用户输入的密码是否正确,如果是123,则为正确,如果不是,就错误
    基于nodejs+vue全国公考岗位及报考人数分析
    Java 基础 进程与线程
    如何确保ChatGPT在文本生成中遵循道德和伦理准则?
    canvas 状态管理
    什么GAN生成对抗网络?生成对抗网络可以干什么?
    C#跨线程刷新前台UI
    如何在做gpt2中文模型搭建时出现以下bug?
    信号上的串联电阻是如何改善信号质量的
    excel中 将一列数字按照,分割开
  • 原文地址:https://blog.csdn.net/hlayumi1234567/article/details/128177547