《数字图像处理(MATLAB版)》相关算法代码及其分析(2)

news2024/9/23 3:20:31

目录

1 将8连通边界转换为4连通边界

1.1 移除对角线转折

1.2 插入额外像素

1.3 总结

2 将边界信息转换为二进制图像

2.1 函数定义

2.2 参数处理和验证

2.3 默认大小参数设置

2.4 根据参数调整边界位置

2.5 生成二进制图像

2.6 错误处理

2.7 总结

3 对二值图像边界的跟踪和提取

3.1 函数描述

3.2 参数处理

3.3 对象标记

3.4 图像填充

3.5 边界跟踪

3.6 边界坐标存储

3.7 结果修正

3.8 结果输出

3.9 总结


1 将8连通边界转换为4连通边界

function rc_new = bound2four(rc)
%BOUND2FOUR Convert 8-connected boundary to 4-connected boundary.
%   RC_NEW = BOUND2FOUR(RC) converts an eight-connected boundary to a
%   four-connected boundary.  RC is a P-by-2 matrix, each row of
%   which contains the row and column coordinates of a boundary
%   pixel.  BOUND2FOUR inserts new boundary pixels wherever there is
%   a diagonal connection.

%   Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins
%   Digital Image Processing Using MATLAB, Prentice-Hall, 2004
%   $Revision: 1.4 $  $Date: 2003/11/21 14:20:21 $

if size(rc, 1) > 1
   % Phase 1: remove diagonal turns, one at a time until they are all gone.
   done = 0;
   rc1 = [rc(end - 1, :); rc];
   while ~done
      d = diff(rc1, 1);
      diagonal_locations = all(d, 2);
      double_diagonals = diagonal_locations(1:end - 1) & ...
          (diff(diagonal_locations, 1) == 0);
      double_diagonal_idx = find(double_diagonals);
      turns = any(d(double_diagonal_idx, :) ~= ...
                  d(double_diagonal_idx + 1, :), 2);
      turns_idx = double_diagonal_idx(turns);
      if isempty(turns_idx)
         done = 1;
      else
         first_turn = turns_idx(1);
         rc1(first_turn + 1, :) = (rc1(first_turn, :) + ...
                                   rc1(first_turn + 2, :)) / 2;
         if first_turn == 1
            rc1(end, :) = rc1(2, :);
         end
      end
   end
   rc1 = rc1(2:end, :);
end

% Phase 2: insert extra pixels where there are diagonal connections.

rowdiff = diff(rc1(:, 1));
coldiff = diff(rc1(:, 2));

diagonal_locations = rowdiff & coldiff;
num_old_pixels = size(rc1, 1);
num_new_pixels = num_old_pixels + sum(diagonal_locations);
rc_new = zeros(num_new_pixels, 2);

% Insert the original values into the proper locations in the new RC
% matrix.
idx = (1:num_old_pixels)' + [0; cumsum(diagonal_locations)];
rc_new(idx, :) = rc1;

% Compute the new pixels to be inserted.
new_pixel_offsets = [0 1; -1 0; 1 0; 0 -1];
offset_codes = 2 * (1 - (coldiff(diagonal_locations) + 1)/2) + ...
    (2 - (rowdiff(diagonal_locations) + 1)/2);
new_pixels = rc1(diagonal_locations, :) + ...
    new_pixel_offsets(offset_codes, :); 

% Where do the new pixels go?
insertion_locations = zeros(num_new_pixels, 1);
insertion_locations(idx) = 1;
insertion_locations = ~insertion_locations;

% Insert the new pixels.
rc_new(insertion_locations, :) = new_pixels;

这段代码的目的是将一个8连通边界转换为4连通边界。在数字图像处理中,连通性是衡量像素之间关系的一种方式。8连通边界意味着边界上的每个像素与其周围的8个像素(水平、垂直和对角线方向)都可能相连。而4连通边界则仅考虑水平和垂直方向的相邻像素。该转换过程涉及两个阶段:首先是移除所有对角线转折点,然后是在需要的位置插入额外的像素以确保4连通性。

1.1 移除对角线转折

  1. 初始化:复制输入的边界坐标rcrc1并在rc1的开头添加rc的倒数第二行。这样做是为了处理循环边界条件。

  2. 循环处理:通过计算rc1的差分d,找出所有对角线连接的位置。这里,对角线连接是指在两个方向(行和列)上都有变化的连接。

  3. 双重对角线和转折点检测:接下来,识别连续的对角线连接(双重对角线)并找出其中的转折点。转折点是指相邻的对角线连接在方向上有所不同的地方。

  4. 处理转折点:对于每个找到的转折点,通过在转折点位置插入一个新的像素(这个像素的坐标是转折点前后两个像素坐标的平均值)来移除转折。如果处理的是第一个转折点,还需要更新rc1的最后一行,以保持边界的闭合性。

  5. 循环结束条件:当没有更多转折点可以处理时,结束循环。

1.2 插入额外像素

  1. 计算差分:计算rc1中行和列的差分,以找出对角线连接的位置。

  2. 确定新像素数量和位置:根据对角线连接的数量,计算新的边界坐标矩阵rc_new的大小,并初始化为零矩阵。然后,计算原始像素和新插入像素在rc_new中的正确位置。

  3. 计算新像素坐标:对于每个需要插入的新像素,根据其相对于原始对角线连接的位置,计算新像素的坐标。

  4. 插入操作:在rc_new中填充原始像素和新计算的像素,完成4连通边界的构建。

1.3 总结

总的来说,这段代码的目的是将一个8连通边界转换为4连通边界,它主要分为两个阶段:第一阶段是移除所有对角线转折,直到它们全部消失;第二阶段是在存在对角连接的位置插入额外的像素。这段代码通过精心设计的算法步骤实现了从8连通边界到4连通边界的转换,保证了数字图像处理中边界连通性的正确处理。

2 将边界信息转换为二进制图像

function B = bound2im(b, M, N, x0, y0)
%BOUND2IM Converts a boundary to an image.
%   B = BOUND2IM(b) converts b, an np-by-2 or 2-by-np array
%   representing the integer coordinates of a boundary, into a binary
%   image with 1s in the locations defined by the coordinates in b
%   and 0s elsewhere. 
%
%   B = BOUND2IM(b, M, N) places the boundary approximately centered
%   in an M-by-N image. If any part of the boundary is outside the
%   M-by-N rectangle, an error is issued.  
%
%   B = BOUND2IM(b, M, N, X0, Y0) places the boundary in an image of
%   size M-by-N, with the topmost boundary point located at X0 and
%   the leftmost point located at Y0. If the shifted boundary is
%   outside the M-by-N rectangle, an error is issued. XO and X0 must
%   be positive integers. 

%   Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins
%   Digital Image Processing Using MATLAB, Prentice-Hall, 2004
%   $Revision: 1.6 $  $Date: 2003/06/14 16:21:28 $

[np, nc] = size(b);
if np < nc
   b = b'; % To convert to size np-by-2.
   [np, nc] = size(b);
end

% Make sure the coordinates are integers.
x = round(b(:, 1)); 
y = round(b(:, 2));

% Set up the default size parameters. 
x = x - min(x) + 1;
y = y - min(y) + 1;
B = false(max(x), max(y));
C = max(x) - min(x) + 1;
D = max(y) - min(y) + 1;

if nargin == 1  
   % Use the preceding default values.
elseif nargin == 3
   if C > M | D > N
      error('The boundary is outside the M-by-N region.')
   end
   % The image size will be M-by-N. Set up the parameters for this.
   B = false(M, N);
   % Distribute extra rows approx. even between top and bottom.
   NR = round((M - C)/2); 
   NC = round((N - D)/2); % The same for columns.
   x = x + NR; % Offset the boundary to new position.
   y = y + NC;  
elseif nargin == 5
   if x0 < 0 | y0 < 0
      error('x0 and y0 must be positive integers.')
   end
   x = x + round(x0) - 1;
   y = y + round(y0) - 1;
   C = C + x0 - 1;
   D = D + y0 - 1;
   if C > M | D > N
      error('The shifted boundary is outside the M-by-N region.')
   end
   B = false(M, N);
else
   error('Incorrect number of inputs.') 
end

B(sub2ind(size(B), x, y)) = true;

这段代码定义了一个名为 bound2im 的函数,它的主要作用是将一个边界(由一系列坐标点组成)转换成一个二进制图像。在这个二进制图像中,边界上的点被标记为 1,其他位置则为 0。下面是对这段代码的详细分析:

2.1 函数定义

function B = bound2im(b, M, N, x0, y0)

这表示 bound2im 是一个函数,它可以接收从1到5个参数:

  • b:一个 np-by-2 或 2-by-np 的数组,代表边界的整数坐标。
  • M 和 N(可选):指定输出图像的大小(行数和列数)。
  • x0 和 y0(可选):指定边界在图像中的起始位置。

函数返回一个二进制图像 B

2.2 参数处理和验证

首先,函数检查输入边界 b 的尺寸,并确保其为 np-by-2 的格式。如果不是,就将其转置。这样做是为了确保后续操作中坐标的使用是正确的。

接着,函数通过取整操作确保坐标都是整数值,因为图像中的位置索引必须是整数。

2.3 默认大小参数设置

如果没有指定图像的大小(即只传入了 b 参数),函数会根据边界的最小和最大坐标计算出一个默认的图像大小。这样做的目的是让整个边界都能够被包含在生成的图像中。

2.4 根据参数调整边界位置

  • 如果只给出了边界 b,那么函数会创建一个足够大的图像来容纳整个边界,并将边界放在图像的左上角。
  • 如果给出了图像大小 M 和 N,但没有指定边界的起始位置,那么边界会被置于图像的大致中心位置。此时,如果边界超出了指定的图像大小,函数会报错。
  • 如果同时给出了图像大小和边界的起始位置 x0 和 y0,边界会根据这些位置进行偏移。同样,如果偏移后的边界超出了图像大小,函数也会报错。

2.5 生成二进制图像

最后,函数使用 false 初始化一个大小为 M-by-N 的二进制图像矩阵 B,然后根据调整后的边界坐标,在相应的位置将 B 中的值设置为 true,从而生成最终的边界图像。

2.6 错误处理

  • 如果 nargin(传入的参数数量)不符合要求,函数会报告“Incorrect number of inputs”错误。
  • 如果边界超出了指定的图像区域,或者 x0y0 不是正整数,函数同样会报错。

2.7 总结

这个函数是数字图像处理中一个常用的功能,它能够将边界信息转换为二进制图像形式,非常适合用于图像处理、计算机视觉等领域的前期数据准备工作。通过灵活地调整输入参数,用户可以控制边界在输出图像中的位置和大小。

3 对二值图像边界的跟踪和提取

function B = boundaries(BW, conn, dir)
%BOUNDARIES Trace object boundaries.  
%   B = BOUNDARIES(BW) traces the exterior boundaries of objects in
%   the binary image BW.  B is a P-by-1 cell array, where P is the
%   number of objects in the image. Each cell contains a Q-by-2
%   matrix, each row of which contains the row and column coordinates
%   of a boundary pixel.  Q is the number of boundary pixels for the
%   corresponding object.  Object boundaries are traced in the
%   clockwise direction.
%
%   B = BOUNDARIES(BW, CONN) specifies the connectivity to use when
%   tracing boundaries.  CONN may be either 8 or 4.  The default
%   value for CONN is 8.
%
%   B = BOUNDARIES(BW, CONN, DIR) specifies the direction used for
%   tracing boundaries.  DIR should be either 'cw' (trace boundaries
%   clockwise) or 'ccw' (trace boundaries counterclockwise).  If DIR
%   is omitted BOUNDARIES traces in the clockwise direction.

%   Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins
%   Digital Image Processing Using MATLAB, Prentice-Hall, 2004
%   $Revision: 1.6 $  $Date: 2003/11/21 14:22:07 $

if nargin < 3
   dir = 'cw';
end

if nargin < 2
   conn = 8;
end

L = bwlabel(BW, conn);

% The number of objects is the maximum value of L.  Initialize the
% cell array B so that each cell initially contains a 0-by-2 matrix.
numObjects = max(L(:));
if numObjects > 0
   B = {zeros(0, 2)};
   B = repmat(B, numObjects, 1);
else
   B = {};
end

% Pad label matrix with zeros.  This lets us write the
% boundary-following loop without worrying about going off the edge
% of the image. 
Lp = padarray(L, [1 1], 0, 'both');

% Compute the linear indexing offsets to take us from a pixel to its
% neighbors.  
M = size(Lp, 1);
if conn == 8
   % Order is N NE E SE S SW W NW.
   offsets = [-1, M - 1, M, M + 1, 1, -M + 1, -M, -M-1];
else
   % Order is N E S W.
   offsets = [-1, M, 1, -M];
end

% next_search_direction_lut is a lookup table.  Given the direction
% from pixel k to pixel k+1, what is the direction to start with when
% examining the neighborhood of pixel k+1?
if conn == 8
   next_search_direction_lut = [8 8 2 2 4 4 6 6];
else
   next_search_direction_lut = [4 1 2 3];
end

% next_direction_lut is a lookup table.  Given that we just looked at
% neighbor in a given direction, which neighbor do we look at next? 
if conn == 8
   next_direction_lut = [2 3 4 5 6 7 8 1];
else
   next_direction_lut = [2 3 4 1];
end

% Values used for marking the starting and boundary pixels.
START    = -1;
BOUNDARY = -2;

% Initialize scratch space in which to record the boundary pixels as
% well as follow the boundary.
scratch = zeros(100, 1);

% Find candidate starting locations for boundaries.
[rr, cc] = find((Lp(2:end-1, :) > 0) & (Lp(1:end-2, :) == 0));
rr = rr + 1;

for k = 1:length(rr)
   r = rr(k);
   c = cc(k);
   if (Lp(r,c) > 0) & (Lp(r - 1, c) == 0) & isempty(B{Lp(r, c)})
      % We've found the start of the next boundary.  Compute its
      % linear offset, record which boundary it is, mark it, and
      % initialize the counter for the number of boundary pixels.
      idx = (c-1)*size(Lp, 1) + r;
      which = Lp(idx);
      
      scratch(1) = idx;
      Lp(idx) = START;
      numPixels = 1;
      currentPixel = idx;
      initial_departure_direction = [];
      
      done = 0;
      next_search_direction = 2;
      while ~done
         % Find the next boundary pixel.
         direction = next_search_direction;
         found_next_pixel = 0;
         for k = 1:length(offsets)
            neighbor = currentPixel + offsets(direction);
            if Lp(neighbor) ~= 0
               % Found the next boundary pixel.
               
               if (Lp(currentPixel) == START) & ...
                      isempty(initial_departure_direction)
                  % We are making the initial departure from
                  % the starting pixel.
                  initial_departure_direction = direction;
                  
               elseif (Lp(currentPixel) == START) & ...
                      (initial_departure_direction == direction)
                  % We are about to retrace our path.
                  % That means we're done.
                  done = 1;
                  found_next_pixel = 1;
                  break;
               end
               
               % Take the next step along the boundary.
               next_search_direction = ...
                   next_search_direction_lut(direction);
               found_next_pixel = 1;
               numPixels = numPixels + 1;
               if numPixels > size(scratch, 1)
                  % Double the scratch space.
                  scratch(2*size(scratch, 1)) = 0;
               end
               scratch(numPixels) = neighbor;
               
               if Lp(neighbor) ~= START
                  Lp(neighbor) = BOUNDARY;
               end
               
               currentPixel = neighbor;
               break;
            end
            
            direction = next_direction_lut(direction);
         end
         
         if ~found_next_pixel
            % If there is no next neighbor, the object must just
            % have a single pixel.
            numPixels = 2;
            scratch(2) = scratch(1);
            done = 1;
         end
      end
      
      % Convert linear indices to row-column coordinates and save
      % in the output cell array. 
      [row, col] = ind2sub(size(Lp), scratch(1:numPixels));
      B{which} = [row - 1, col - 1];
   end
end

if strcmp(dir, 'ccw')
   for k = 1:length(B)
      B{k} = B{k}(end:-1:1, :);
   end
end

这段代码实现了对二值图像中对象的边界进行跟踪,最终输出一个包含所有对象边界坐标的 cell 数组。

主要函数 boundaries 接受三个参数:BW 表示输入的二值图像,conn 表示连接性(8 连通或 4 连通),dir 表示跟踪边界的方向(顺时针或逆时针)。根据不同的输入情况,函数会进行相应的处理。其中,首先根据输入参数确定连接性和跟踪方向,然后使用 bwlabel 函数标记输入二值图像中的对象,并初始化一个 cell 数组 B 用于存储边界坐标。

接着,对标记矩阵进行填充操作以简化边界跟踪过程,并定义了一些变量和查找表用于指导边界跟踪的方向。通过在图像中寻找起始位置,然后按照设定的方向依次跟踪边界像素,直到形成完整的边界闭合路径。最后,根据跟踪方向对边界路径进行修正,最终将每个对象的边界坐标存储在 cell 数组 B 中,并按照设定的方向进行排序。

需要注意的是,该代码是基于 MATLAB 的图像处理工具箱编写的,涉及到图像处理中的边界跟踪算法,主要通过对相邻像素进行搜索和遍历完成对象边界的提取。

3.1 函数描述

函数名:boundaries

功能:跟踪二值图像中对象的边界

输入参数:

  • BW:二值图像
  • conn:连接性(8 连通或 4 连通,默认为 8 连通)
  • dir:跟踪方向(顺时针或逆时针,默认为顺时针)

输出参数:

  • B:包含所有对象边界坐标的 cell 数组

3.2 参数处理

  • 检查输入参数,确保足够数量
  • 如果参数缺失,设置默认值
  • 确定连接性和跟踪方向设置

3.3 对象标记

  • 使用 bwlabel 函数对输入的二值图像进行对象标记
  • 获取每个对象的唯一标识
  • 初始化存储边界坐标的 cell 数组 B

3.4 图像填充

  • 对标记矩阵进行填充操作,简化边界跟踪
  • 定义变量和查找表指导边界跟踪方向

3.5 边界跟踪

  • 在图像中搜索起始位置
  • 按照设定方向依次跟踪边界像素,形成闭合路径
  • 考虑边界的闭合性和连通性

3.6 边界坐标存储

  • 将每个对象的边界坐标存储在 cell 数组 B 中
  • 使用线性索引转换为行列坐标,并存储在对应的 cell 元素中

3.7 结果修正

  • 根据跟踪方向对边界路径进行修正,确保正确的边界顺序

3.8 结果输出

  • 将存储了对象边界坐标的 cell 数组 B 输出作为函数的返回结果

3.9 总结

这段代码实现了对输入的二值图像中每个对象的边界进行跟踪提取,首先对对象进行标记并初始化存储边界坐标的数据结构,然后通过边界跟踪算法沿着对象的边界逐点进行路径提取,并最终根据指定的方向(顺时针或逆时针)对提取的边界路径进行修正,最终输出每个对象的完整边界坐标。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1487569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【EAI 028】Video as the New Language for Real-World Decision Making

Paper Card 论文标题&#xff1a;Video as the New Language for Real-World Decision Making 论文作者&#xff1a;Sherry Yang, Jacob Walker, Jack Parker-Holder, Yilun Du, Jake Bruce, Andre Barreto, Pieter Abbeel, Dale Schuurmans 作者单位&#xff1a;Google DeepMi…

Sqli-labs靶场第16关详解[Sqli-labs-less-16]自动化注入-SQLmap工具注入

Sqli-labs-Less-16 #自动化注入-SQLmap工具注入 SQLmap用户手册&#xff1a;文档介绍 - sqlmap 用户手册 以非交互式模式运行 --batch 当你需要以批处理模式运行 sqlmap&#xff0c;避免任何用户干预 sqlmap 的运行&#xff0c;可以强制使用 --batch 这个开关。这样&#xff0…

如何使用恢复软件恢复删除的文件?回收站文件恢复攻略

随着计算机在日常生活中的普及&#xff0c;文件的管理和存储成为我们不可或缺的技能。在Windows操作系统中&#xff0c;回收站作为一个帮助我们管理文件删除的重要工具&#xff0c;在误删了一些重要文件之后&#xff0c;我们可能会因为找不到回收站中恢复的文件而感到困惑。本文…

动态规划DP之背包问题3---多重背包问题

目录 DP分析&#xff1a; 优化&#xff1a; 二进制优化 例题&#xff1a; 01背包是每个物品只有一个&#xff0c;完全背包问题是每个物品有无限个。 那么多重背包问题就是 每个物品有有限个。 有 N 种物品和一个容量是 V 的背包。 第 i 种物品最多有 si 件&#xff0c;每件体…

安卓手机安装termux、kali linux及基本配置

相关阅读&#xff1a;Termux 高级终端安装使用配置教程 | 国光 百度安全验证 该文安装的 kali liunx 应该是简易版的&#xff0c;没有相关工具 一、下载安装termux 建议通过 f-droid 应用市场下载链接termux&#xff0c;点击即直接下载。 二、配置termux 1.更换镜像源 te…

【大厂AI课学习笔记NO.61】环境部署的选择

主要是选择单机和分布式、生产和开发环境的规划等。 开发环境、测试环境、预发布环境和生产环境是软件开发和部署过程中常见的几个环境&#xff0c;它们各自的定义、区别、联系以及实现的关键技术如下&#xff1a; 1. 开发环境&#xff08;Development Environment&#xff09…

深入理解Docker自定义网络:构建高效的容器网络环境

文章目录 一、docker自定义网络介绍1.1 docker自定义网络介绍1.2 使用技术的优势1.3 基本使用流程 二、实战操作2.1 模式理论介绍bridge模式(默认模式)host模式 2.2 模式特点查看桥接模式的特点查看仅主机模式的特点 2.3 实战操作bridge模式host模式自定义网络 一、docker自定义…

STM32单片机基本原理与应用(十)

汉字显示实验 显示原理 字库文件的实际上包含了每个汉字的模。单片机应用经常会用到液晶显示或者LED点阵屏&#xff0c;是用点阵的方式显示的&#xff0c;要显示汉字或字符的时候会用到字模&#xff0c;字模就是字在点阵上显示时对应的编码。以字模的方式存储图形或者文字&am…

【本科组冠名奖】2023年第八届数维杯数学建模挑战赛获奖感言

美国大学生数学建模竞赛已结束过半&#xff0c;现在又迎来了2024年第九届数维杯国赛&#xff0c;准备参加今年数维杯国赛的同学&#xff0c;今天我们一起看看去年优秀的选手都有什么获奖感言吧~希望能帮到更多热爱数学建模的同学。据说文末在看点赞的大佬都会直冲国奖呢&#x…

【.NET Core】.NET中的流(Stream)

【.NET Core】.NET中的流&#xff08;Stream&#xff09; 文章目录 【.NET Core】.NET中的流&#xff08;Stream&#xff09;一、流&#xff08;Stream&#xff09;1.1 FileStream类1.2 IsolatedStorageFileStream类1.3 MemoryStream类1.4 BufferedStream类1.5 NetworkStream类…

BUUCTF---[极客大挑战 2019]Http1

1.题目描述&#xff0c;在地址框输入下面的网址 2.来到页面&#xff0c;ctrlu查看源码&#xff0c;仔细观察会看到一个.php的跳转页面 3.点进去页面提示It doesnt come from https://Sycsecret.buuoj.cn 4.页面提示它不是来源于这个网址&#xff0c;我们需要用bp抓包对数据进行…

matlab 写入格式化文本文件

目录 一、save函数 二、fprintf函数 matlab 写入文本文件可以使用save和fprintf函数 save输出结果: fprintf输出结果: 1.23, 2.34, 3.45 4.56, 5.67, 6.78 7.89, 8.90, 9.01 可以看出fprintf输出结果更加人性化,符合要求,下面分别介绍。 一、save函数 …

深入了解 JavaScript 混淆加密和环境检测

JavaScript混淆加密是一种通过修改代码结构和命名约定来增加代码的复杂性&#xff0c;使其难以被理解和逆向工程的技术。在这篇文章中&#xff0c;我们将深入探讨JS混淆加密的一些逻辑&#xff0c;并介绍如何通过环境检测来提高代码的安全性。我们将使用案例代码演示这些概念。…

外汇110:社交媒体上的金融欺诈激增,网民该如何识别骗局?

社交媒体平台上的金融欺诈正在以令人担忧的速度增加。从某种程度上来说&#xff0c;社交媒体已成为诈骗者的门户&#xff0c;因为它使欺诈者能够方便地与用户联系&#xff0c;并创建一个隐藏在虚假社交媒体资料后面、充斥着非法投资内容的在线角色。 由于社交媒体在我们日常生活…

智慧城市中的公共服务创新:让城市生活更便捷

目录 一、引言 二、智慧城市公共服务创新的实践 1、智慧交通系统 2、智慧医疗服务 3、智慧教育系统 4、智慧能源管理 三、智慧城市公共服务创新的挑战 四、智慧城市公共服务创新的前景 五、结论 一、引言 随着信息技术的迅猛发展&#xff0c;智慧城市已成为现代城市发…

基于React低代码平台开发:构建高效、灵活的应用新范式

文章目录 一、React与低代码平台的结合优势二、基于React的低代码平台开发挑战三、基于React的低代码平台开发实践四、未来展望《低代码平台开发实践&#xff1a;基于React》编辑推荐内容简介作者简介目录前言为什么要写这本书 读者对象如何阅读本书 随着数字化转型的深入&…

用BIO实现tomcat

一、前言 本课程的难度较高&#xff0c;需要将Servlet原理和IO课程全部学完。 二、当前项目使用方式 (1).自定义servlet 自定义servlet需要实现WebServlet并且实现name和urlMapping 重启进行访问 http://localhost:8090/myServlet (2).自定义html 重启进行访问 http://loc…

四川古力未来科技抖音小店:未来零售的新风口

随着互联网的快速发展&#xff0c;电商行业日新月异&#xff0c;短视频平台抖音凭借其庞大的用户群体和独特的内容形式&#xff0c;已经成为当下最热门的社交媒体之一。抖音小店作为抖音平台上的一个重要功能&#xff0c;正逐渐展现出其巨大的商业潜力和发展前景。本文将探讨抖…

【脑科学相关合集】有关脑影像数据相关介绍的笔记及有关脑网络的笔记合集

【脑科学相关合集】有关脑影像数据相关介绍的笔记及有关脑网络的笔记合集 前言脑模板方面相关笔记清单 基于脑网络的方法方面数据基本方面 前言 这里&#xff0c;我将展开有关我自己关于脑影像数据相关介绍的笔记及有关脑网络的笔记合集。其中&#xff0c;脑网络的相关论文主要…

C++原子变量的使用案例

说明 核心原子变量是pDeviceStatus&#xff0c;该变量的夸线程修改&#xff0c;就不需要使用锁了&#xff1b; std::atomic<IPDeviceStatus*> pDeviceStatus new IPDeviceStatus(); 代码功能 某公共场所使用的IP喇叭&#xff0c;类似物联网设备&#xff0c;基于嵌入…