当前位置: 首页 > news >正文

在 Python 中使用 Pillow 进行图像处理【3/4】

第三部分

一、腐蚀和膨胀

        您可以查看名为 的图像文件dot_and_hole.jpg,您可以从本教程链接的存储库中下载该文件:

用于演示 Python Pillow 中的腐蚀和膨胀的示例图像

        该二值图像的左侧显示黑色背景上的白点,而右侧显示纯白色部分中的黑洞。

        侵蚀是从图像边界去除白色像素的过程。您可以通过使用二进制图像 ImageFilter.MinFilter(3)作为该方法的参数来实现此目的.filter()3x3此过滤器将像素的值替换为以该像素为中心的阵列中九个像素的最小值。在二值图像中,这意味着如果某个像素的任何相邻像素为零,则该像素的值将为零。

    ImageFilter.MinFilter(3)通过对图像应用多次,您可以看到侵蚀的效果dot_and_hole.jpg。您应该继续使用与上一节中相同的 REPL 会话:

>>>

>>> from PIL import ImageFilter
>>> filename = "dot_and_hole.jpg">>> with Image.open(filename) as img:
...     img.load()
...>>> for _ in range(3):
...     img = img.filter(ImageFilter.MinFilter(3))
...>>> img.show()

         您已使用循环应用了三次过滤器for。此代码给出以下输出:

Python Pillow 中的侵蚀

        由于侵蚀,圆点缩小了,但孔却变大了。

        膨胀是与腐蚀相反的过程。白色像素被添加到二值图像的边界。您可以使用 来实现膨胀ImageFilter.MaxFilter(3),如果某个像素的任何邻居是白色,则该像素将其转换为白色。

        您可以对包含点和孔的同一图像应用膨胀,您可以再次打开并加载该图像:

>>>

>>> with Image.open(filename) as img:
...     img.load()
...>>> for _ in range(3):
...     img = img.filter(ImageFilter.MaxFilter(3))
...>>> img.show()

        点现在变大了,洞缩小了:

Python Pillow 中的膨胀

        您可以同时使用腐蚀和膨胀来填充孔洞并从二值图像中删除小对象。使用带有点和孔的图像,您可以执行十次腐蚀循环来删除点,然后执行十次膨胀循环以将孔恢复到其原始大小:

>>>

>>> with Image.open(filename) as img:
...     img.load()
...>>> for _ in range(10):
...     img = img.filter(ImageFilter.MinFilter(3))
...>>> img.show()>>> for _ in range(10):
...     img = img.filter(ImageFilter.MaxFilter(3))
...>>> img.show()

        您可以使用第一个for循环执行十个侵蚀循环。此阶段的图像如下:

Python Pillow 中的侵蚀

        该点已消失,并且该孔比原始图像中的孔更大。第二个for循环执行十个膨胀周期,使孔返回到其原始大小:

Python Pillow 中的膨胀

        然而,该点不再出现在图像中。侵蚀和膨胀修改了图像以保留孔但移除点。所需的腐蚀和膨胀的数量取决于图像和您想要实现的目标。通常,您需要通过反复试验找到正确的组合。

        您可以定义函数来执行多个腐蚀和膨胀循环:

>>>

>>> def erode(cycles, image):
...     for _ in range(cycles):
...          image = image.filter(ImageFilter.MinFilter(3))
...     return image
...>>> def dilate(cycles, image):
...     for _ in range(cycles):
...          image = image.filter(ImageFilter.MaxFilter(3))
...     return image
...

        这些函数使对图像进行腐蚀和膨胀实验变得更加容易。当您继续将猫放入修道院时,您将在下一节中使用这些函数。

二、使用阈值分割图像

        您可以对之前获得的阈值图像使用一系列侵蚀和膨胀,以删除遮罩中不代表猫的部分,并填充包含猫的区域中的任何间隙。一旦您尝试了腐蚀和膨胀,您将能够在试错过程中使用有根据的猜测来找到腐蚀和膨胀的最佳组合,以实现理想的蒙版。

        从您之前获得的图像开始img_cat_threshold,您可以从一系列腐蚀开始,以删除代表原始图像中背景的白色像素。您应该继续在与前面部分相同的 REPL 会话中工作:

>>>

>>> step_1 = erode(12, img_cat_threshold)
>>> step_1.show()

        腐蚀后的阈值图像不再包含代表图像背景的白色像素:

阈值处理后的腐蚀和膨胀

        然而,剩下的面具比猫的整体轮廓要小,并且内部有孔和间隙。您可以执行扩张来填补空白:

>>>

>>> step_2 = dilate(58, step_1)
>>> step_2.show()

        五十八个膨胀周期填充了掩模中的所有孔,得到以下图像:

        不过,这个面具太大了。因此,您可以通过一系列侵蚀来完成该过程:

>>>

>>> cat_mask = erode(45, step_2)
>>> cat_mask.show()

结果是一个可以用来分割猫图像的蒙版:

Python Pillow 中的图像分割掩码

您可以通过模糊此蒙版来避免二元蒙版的锐边。您必须首先将其从二值图像转换为灰度图像:

>>>

>>> cat_mask = cat_mask.convert("L")
>>> cat_mask = cat_mask.filter(ImageFilter.BoxBlur(20))
>>> cat_mask.show()

过滤BoxBlur()器返回以下掩码:

Python Pillow 中的图像分割掩码

面具现在看起来像一只猫!现在您已准备好从背景中提取猫的图像:

>>>

>>> blank = img_cat.point(lambda _: 0)
>>> cat_segmented = Image.composite(img_cat, blank, cat_mask)
>>> cat_segmented.show()

        首先,创建一个与 img_cat 大小相同的空白图像。您可以使用 .point() 并将所有值设置为零,从 img_cat 创建一个新的 Image 对象。接下来,使用 PIL.Image 中的 composite() 函数创建由 img_cat 和空白组成的图像,并使用 cat_mask 来确定使用每个图像的哪些部分。合成图像如下所示:

Python Pillow 中猫的分割图像

您已经分割了猫的图像并从背景中提取了猫。

三、图像叠加使用Image.paste()

您可以更进一步,将猫的分割图像从本教程的图像存储库粘贴到修道院庭院的图像中:

>>>

>>> filename_monastery = "monastery.jpg"
>>> with Image.open(filename_monastery) as img_monastery:
...     img_monastery.load()>>> img_monastery.paste(
...     img_cat.resize((img_cat.width // 5, img_cat.height // 5)),
...     (1300, 750),
...     cat_mask.resize((cat_mask.width // 5, cat_mask.height // 5)),
... )>>> img_monastery.show()

        您曾经.paste()将一张图像粘贴到另一张图像上。该方法可以与三个参数一起使用:

  • 第一个参数是要粘贴的图像//。您使用整数除法运算符 ( ) 将图像大小调整为其大小的五分之一。
  • 第二个参数是主图像中要粘贴第二张图片的位置。该元组包含主图像中要放置要粘贴的图像左上角的坐标。
  • 如果您不想粘贴整个图像,第三个参数提供您希望使用的蒙版。

您已使用通过阈值处理、腐蚀和膨胀过程获得的蒙版来粘贴没有背景的猫。输出如下图所示:

叠加在修道院图像上的猫的分割图像

        您已将猫从一张图像中分割出来,并将其放入另一张图像中,以显示猫安静地坐在修道院庭院中,而不是原始图像中它坐在田野中。

四、创建水印

        本示例中的最终任务是将 Real Python 徽标作为水印添加到图像中。您可以从本教程随附的存储库中获取带有 Real Python 徽标的图像文件:

        获取图像: 单击此处访问您将使用 Pillow 操作和处理的图像。

您应该继续在同一个 REPL 会话中工作:

>>>

>>> logo = "realpython-logo.png"
>>> with Image.open(logo) as img_logo:
...     img_logo.load()
...>>> img_logo = Image.open(logo)
>>> img_logo.show()

这是全尺寸的彩色徽标:

真正的Python标志

您可以将图像更改为灰度并使用阈值.point()将其转换为黑白图像。您还可以缩小其尺寸并将其转换为轮廓图像:

>>>

>>> img_logo = img_logo.convert("L")
>>> threshold = 50
>>> img_logo = img_logo.point(lambda x: 255 if x > threshold else 0)
>>> img_logo = img_logo.resize(
...     (img_logo.width // 2, img_logo.height // 2)
... )
>>> img_logo = img_logo.filter(ImageFilter.CONTOUR)
>>> img_logo.show()

输出显示 Real Python 徽标的轮廓。该轮廓非常适合用作图像上的水印:

Python Pillow 中真实 Python 徽标的轮廓

要将其用作水印,您需要反转颜色,使背景为黑色,只有要保留的轮廓为白色。您可以.point()再次使用以下方法来实现此目的:

>>>

>>> img_logo = img_logo.point(lambda x: 0 if x == 255 else 255)
>>> img_logo.show()

您已经转换了值为 的像素255并为它们分配了值0,将它们从白色像素转换为黑色像素。您将剩余的像素设置为白色。反转轮廓标志如下所示:

Python Pillow 中真实 Python 徽标的轮廓

最后一步是将这个轮廓粘贴到坐在修道院庭院里的猫的图像上。您可以.paste()再次使用:

>>>

>>> img_monastery.paste(img_logo, (480, 160), img_logo)
>>> img_monastery.show()

第一个参数.paste()表示您要粘贴的图像,第三个参数表示蒙版。在本例中,您将使用相同的图像作为蒙版,因为该图像是二值图像。第二个参数提供要粘贴图像的区域的左上角坐标。

该图像现在包含一个真正的 Python 水印:

带有 Real Python 水印的修道院里的猫图像

水印具有矩形轮廓,这是您之前使用的轮廓过滤器的结果。如果您希望删除此轮廓,可以使用 裁剪图像.crop()。这是一个您可以自己尝试的练习。

五、使用 NumPy 和 Pillow 进行图像处理

        Pillow 具有多种内置功能和过滤器可供选择。然而,有时您需要进一步操作超出 Pillow 中现有功能的图像。

        您可以借助NumPy进一步操作图像。NumPy 是一个非常流行的用于处理数值数组的 Python 库,它是与 Pillow 一起使用的理想工具。您可以在NumPy 教程:使用 Python 进入数据科学的第一步中了解有关 NumPy 的更多信息。

        将图像转换为 NumPy 数组时,您可以直接对数组中的像素执行所需的任何转换。在 NumPy 中完成处理后,您可以Image使用 Pillow 将数组转换回对象。您需要为此部分安装 NumPy:

(venv) $ python -m pip install numpy

        现在您已经安装了 NumPy,您可以使用 Pillow 和 NumPy 来发现两个图像之间的差异。

5.1 使用 NumPy 相互减去图像

        看看您是否能找出以下两幅图像之间的差异:

使用 Python Pillow 找出差异

        这不是一件难事!然而,你决定作弊并编写一个 Python 程序来为你解决这个难题。您可以从本教程附带的存储库下载图像文件house_left.jpghouse_right.jpg(图像来源):

        获取图像: 单击此处访问您将使用 Pillow 操作和处理的图像。

第一步是使用 Pillow 读取图像并将其转换为 NumPy 数组:

>>>

>>> import numpy as np
>>> from PIL import Image>>> with Image.open("house_left.jpg") as left:
...     left.load()
...
>>> with Image.open("house_right.jpg") as right:
...     right.load()
...>>> left_array = np.asarray(left)
>>> right_array = np.asarray(right)>>> type(left_array)
<class 'numpy.ndarray'>
>>> type(right_array)
<class 'numpy.ndarray'>

        由于left_arrayright_array是 类型的对象numpy.ndarray,因此您可以使用 NumPy 中提供的所有工具来操作它们。您可以从一个数组中减去另一个数组以显示两个图像之间不同的像素:

>>>

>>> difference_array =  right_array - left_array
>>> type(difference_array)
<class 'numpy.ndarray'>

        当您从另一个相同大小的数组中减去一个数组时,结果是另一个与原始数组具有相同形状的数组。Image.fromarray()您可以使用Pillow将此数组转换为图像:

>>>

>>> difference = Image.fromarray(difference_array)
>>> difference.show()

将一个 NumPy 数组减去另一个 NumPy 数组并转换为 Pillow 的结果Image是如下所示的差异图像:

使用 Python Pillow 找出差异

        差异图像仅显示原始图像的三个区域。这些区域突出了两个图像之间的差异。您还可以看到云和栅栏周围有一些噪点,这是由于这些项目周围区域的原始 JPEG 压缩发生了微小变化。

5.2 使用 NumPy 创建图像

        您可以更进一步,使用 NumPy 和 Pillow 从头开始​​创建图像。您可以从创建灰度图像开始。在此示例中,您将创建一个包含正方形的简单图像,但您可以用相同的方式创建更复杂的图像:

>>>

>>> import numpy as np
>>> from PIL import Image>>> square = np.zeros((600, 600))
>>> square[200:400, 200:400] = 255>>> square_img = Image.fromarray(square)
>>> square_img
<PIL.Image.Image image mode=F size=600x600 at 0x7FC7D8541F70>>>> square_img.show()

        您创建一个大小随处包含零的数组600x600。接下来,将数组中心的一组像素的值设置为255

        您可以使用行和列对 NumPy 数组进行索引。在此示例中,第一个切片表示的200:400行。逗号后面的第二个切片表示的列。200399200:400200399

        您可以使用Image.fromarray()将 NumPy 数组转换为 类型的对象Image。上面代码的输出如下所示:

使用 NumPy 和 Python Pillow 生成的图像

        您已经创建了一个包含正方形的灰度图像。当您使用 时,会自动推断图像的模式Image.fromarray()。在这种情况下,使用模式"F",它对应于具有 32 位浮点像素的图像。如果您愿意,可以将其转换为更简单的 8 位像素灰度图像:

>>>

>>> square_img = square_img.convert("L")

        您还可以更进一步,创建彩色图像。您可以重复上述过程来创建三张图像,一张对应于红色通道,另一张对应于绿色通道,最后一张对应于蓝色通道:

>>>

>>> red = np.zeros((600, 600))
>>> green = np.zeros((600, 600))
>>> blue = np.zeros((600, 600))
>>> red[150:350, 150:350] = 255
>>> green[200:400, 200:400] = 255
>>> blue[250:450, 250:450] = 255>>> red_img = Image.fromarray(red).convert("L")
>>> green_img = Image.fromarray(green).convert("L")
>>> blue_img = Image.fromarray((blue)).convert("L")

        您从每个 NumPy 数组创建一个Image对象,并将图像转换为 mode "L",它表示灰度。现在,您可以使用以下命令将这三个单独的图像合并为一个 RGB 图像Image.merge()

>>>

>>> square_img = Image.merge("RGB", (red_img, green_img, blue_img))
>>> square_img
<PIL.Image.Image image mode=RGB size=600x600 at 0x7FC7C817B9D0>>>> square_img.show()

        第一个参数Image.merge()是图像输出的模式。第二个参数是包含各个单波段图像的序列。此代码创建以下图像:

使用 NumPy 和 Python Pillow 生成的彩色图像

        您已将单独的波段组合成 RGB 彩色图像。在下一节中,您将更进一步,使用 NumPy 和 Pillow 创建 GIF 动画。

六、创建动画

        在上一节中,您创建了一个彩色图像,其中包含三个不同颜色的重叠正方形。在本部分中,您将创建一个动画,显示这三个方块合并为一个白色方块。您将创建包含三个正方形的图像的多个版本,并且连续图像之间的正方形位置会略有不同:

>>>

>>> import numpy as np
>>> from PIL import Image>>> square_animation = []
>>> for offset in range(0, 100, 2):
...     red = np.zeros((600, 600))
...     green = np.zeros((600, 600))
...     blue = np.zeros((600, 600))
...     red[101 + offset : 301 + offset, 101 + offset : 301 + offset] = 255
...     green[200:400, 200:400] = 255
...     blue[299 - offset : 499 - offset, 299 - offset : 499 - offset] = 255
...     red_img = Image.fromarray(red).convert("L")
...     green_img = Image.fromarray(green).convert("L")
...     blue_img = Image.fromarray((blue)).convert("L")
...     square_animation.append(
...         Image.merge(
...             "RGB",
...             (red_img, green_img, blue_img)
...         )
...     )
...

        您创建一个名为 的空列表square_animation,用于存储您生成的各种图像。在for循环中,您为红色、绿色和蓝色通道创建 NumPy 数组,如上一节中所做的那样。包含绿色层的数组始终相同,代表图像中心的一个正方形。

        红色方块从移至中心左上角的位置开始。在每个连续帧中,红色方块都会向中心移动,直到在循环的最终迭代中到达中心。蓝色方块最初向右下角移动,然后随着每次迭代向中心移动。

        请注意,在此示例中,您正在迭代range(0, 100, 2),这意味着变量offset以 2 为步长增加。

        您之前了解到可以Image使用 将对象保存到文件中Image.save()。您可以使用相同的功能保存到包含图像序列的 GIF 文件。您调用Image.save()序列中的第一张图像,这是您存储在列表中的第一张图像square_animation

>>>

>>> square_animation[0].save(
...     "animation.gif", save_all=True, append_images=square_animation[1:]
... )

        第一个参数.save()是要保存的文件的文件名。文件名中的扩展名告诉我们.save()需要输出什么文件格式。您还可以在中包含两个关键字参数.save()

  • save_all=True确保序列中的所有图像都被保存,而不仅仅是第一个图像。
  • append_images=square_animation[1:]允许您将序列中的剩余图像附加到 GIF 文件。

        此代码保存animation.gif到文件,然后您可以使用任何图像软件打开 GIF 文件。GIF 默认情况下应该循环,但在某些系统上,您需要添加关键字参数loop=0.save()确保 GIF 循环。您得到的动画如下:

蓝色、绿色和红色方块合并成一个以黑色背景为中心的白色方块

        三个不同颜色的方块合并成一个白色方块。您可以使用不同的形状和不同的颜色创建自己的动画吗?

七、结论

        您已经学习了如何使用 Pillow 处理图像并执行图像处理。如果您喜欢处理图像,您可能想一头扎进图像处理的世界。关于图像处理的理论和实践还有很多东西需要学习。一个很好的起点是Gonzalez 和 Woods 的《数字图像处理》,这是该领域的经典教科书。

        Pillow 并不是唯一可以在 Python 中用于图像处理的库。如果您的目标是执行一些基本处理,那么您在本教程中学到的技术可能就是您所需要的。如果您想深入了解更先进的图像处理技术,例如机器学习和计算机视觉应用,那么您可以使用 Pillow 作为其他库(例如 OpenCV 和 scikit-image)的垫脚石。

相关文章:

在 Python 中使用 Pillow 进行图像处理【3/4】

第三部分 一、腐蚀和膨胀 您可以查看名为 的图像文件dot_and_hole.jpg&#xff0c;您可以从本教程链接的存储库中下载该文件&#xff1a; 该二值图像的左侧显示黑色背景上的白点&#xff0c;而右侧显示纯白色部分中的黑洞。 侵蚀是从图像边界去除白色像素的过程。您可以通过使用…...

【Java】迭代器的next方法

Collection 集合的遍历 概述&#xff1a;Iteration&#xff1a;迭代器&#xff0c;集合的专用遍历方式 Iterator<E> Iterator() 返回在此 collection 的元素上进行迭代的迭代器boolean hasNext() 如果返回仍有元素可以迭代&#xff0c;则返回 trueE next() 返回迭代的下一…...

java智慧工地云平台源码,以物联网、移动互联网技术为基础,结合大数据、云计算等,实现工程管理绿色化、数字化、精细化、智能化的效果

智慧工地将更多人工智能、传感技术、虚拟现实等高科技技术植入到建筑、机械、人员穿戴设施、场地进出关口等各类物体中&#xff0c;围绕人、机、料、法、环等各方面关键因素&#xff0c;彻底改变传统建筑施工现场参建各方现场管理的交互方式、工作方式和管理模式&#xff0c;智…...

Unity 通过jar包形式接入讯飞星火SDK

最近工作上遇到了要接入gpt相关内容的需求&#xff0c;简单实现了一个安卓端接入讯飞星火的UnitySDK。 或者也可以接入WebSocket接口的。本文只讲安卓实现 我使用的Unity版本为2021.3.27f1c2 Android版本为4.2.2 1.下载SDK 登陆讯飞开放平台下载如图所示SDK 2.新建安卓工程…...

python轻量规则引擎rule-engine入门与应用实践

rule-engine是一种轻量级、可选类型的表达式语言&#xff0c;具有用于匹配任意 Python 对象的自定义语法&#xff0c;使用python语言开发。 规则引擎表达式用自己的语言编写&#xff0c;在 Python 中定义为字符串。其语法与 Python 最相似&#xff0c;但也受到 Ruby 的一些启发…...

栓Q八股文: C++ 14/17 新特性

C 14 翻译&#xff1a; 【翻译】C14的新特性简介-腾讯云开发者社区-腾讯云 C 17翻译&#xff1a;【翻译】C17的新特性简介-腾讯云开发者社区-腾讯云 原理&#xff1a;C Lambda 原理和编译器实现_clamda实现原理-CSDN博客...

虚拟世界游戏定制开发:创造独一无二的虚拟体验

在游戏开发领域&#xff0c;虚拟世界游戏定制开发是一项引人注目的任务&#xff0c;旨在满足客户独特的需求和愿景&#xff0c;创造一个完全个性化的虚拟世界游戏。这种类型的游戏开发需要专业的技能、深刻的游戏开发知识和密切的与客户合作&#xff0c;以确保游戏满足客户的期…...

Tomcat及jdk安装下载及环境配置(超超超详解)

我是看了两篇博客安装配置好的 jdk 最详细jdk安装以及配置环境&#xff08;保姆级教程&#xff09;_安装jdk需要配置环境变量吗-CSDN博客 tomcat Tomcat的下载安装与配置及常见问题处理【Win11】 - 鞠雨童 - 博客园 (cnblogs.com) 本篇文章是我解决了很多朋友的tomcat配置问题总…...

专业安卓实时投屏软件:极限投屏(QtScrcpy作者开发)使用说明

基本介绍 极限投屏是一款批量投屏管理安卓设备的软件&#xff0c;是QtScrcpy作者基于QtScrcpyCore开发&#xff0c;主要功能有&#xff1a; 设备投屏&控制&#xff1a;单个控制、批量控制分组管理wifi投屏adb shell快捷指令文件传输、apk安装 更多功能还在持续更新。 极…...

C++:二叉搜索树的原理和模拟实现

文章目录 二叉搜索树二叉搜索树的基本实现原理 二叉搜索树的实现非递归版本的实现递归版本的实现 二叉搜索树 二叉搜索树也叫做二叉排序树&#xff0c;可以是空树&#xff0c;也可以是满足一些要求的二叉树 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点…...

学习视觉CV Transformer (2)--Transformer原理及代码分析

下面结合代码和原理进行深入分析Transformer原理。 2 Transformer深入分析 对于CV初学者来说&#xff0c;其实只需要理解Q K V 的含义和注意力机制的三个计算步骤&#xff1a; Q 和所有 K 计算相似性&#xff1b;对相似性采用 Softmax 转化为概率分布&#xff1b;将概率分布…...

【AI视野·今日CV 计算机视觉论文速览 第271期】Thu, 19 Oct 2023

AI视野今日CS.CV 计算机视觉论文速览 Thu, 19 Oct 2023 Totally 63 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Learning from Rich Semantics and Coarse Locations for Long-tailed Object Detection Authors Lingchen Meng, Xiyang D…...

GoLong的学习之路(四)语法之循环语句

书接上回&#xff0c;上回说到运算符&#xff0c;这次我们说一个编程语言中最重要的一点&#xff1a;流程控制&#xff0c;及循环语句 文章目录 循环语句if else(分支结构)if条件判断特殊写法 for(循环结构)for range(键值循环) switch casegoto(跳转到指定标签)break(跳出循环…...

【Lua语法】字符串

Lua语言中的字符串是不可变值。不能像在C语言中那样直接改变某个字符串中的某个字符&#xff0c;但是可以通过创建一个新字符串的方式来达到修改的目的 print(add2(1 , 2 ,15,3))a "no one"b string.gsub(a , "no" , "on1111")print(a) print…...

程序员节的由来

早在2006年的时候 我就发现了 1024KB1MB 然后恰好又是2的10次方 那时候我就把这一天定义为程序员节了 不过当时并没有太多的知名度。 所以严格意义来讲 距历史记载&#xff0c;程序员应该是由我&#xff08;田尚滨/cagy&#xff09;发明的。 As early as 2006 I found …...

订水商城H5实战教程-03用户协议

目录 1 创建页面2 为文本组件增加事件3 检查用户协议是否勾选最终效果 我们上一篇介绍了打开首页时弹出登录窗口的功能&#xff0c;本篇我们实现一下用户协议。 1 创建页面 功能是点击用户协议的时候打开具体的协议内容&#xff0c;需要先创建一个页面。打开自定义应用&#x…...

淘宝app商品详情源数据API接口(解决滑块问题)可高并发采集

通过API接口采集淘宝商品列表和app商品详情遇到滑块验证码的解决方法&#xff08;带SKU和商品描述&#xff0c;支持高并发&#xff09;&#xff0c;主要是解决了高频情况下的阿里系滑块和必须要N多小号才能解决的反扒问题&#xff0c;以后都可以使用本方法&#xff1a; 大家都…...

xcode15一直显示正在连接iOS17真机问题解决

前言 更新xcode15之后&#xff0c;出现了各种报错问题&#xff0c;可谓是一路打怪啊&#xff0c;解决一个报错问题又来一个。没想到到了最后还能出现一个一直显示正在连接iOS17真机的问题 一直显示正在连接iOS17真机的问题 问题截图如下&#xff1a; 解决方法 1. 打开De…...

stm32通过AT指令与esp8622通信

stm32通过AT指令与esp8622通信 文章目录 stm32通过AT指令与esp8622通信1.tcp通信2.mqtt通信 1.tcp通信 ATCWMODE1 设置为STA模式ATCWJAP_DEF"langtaotech","langtaotechXXX"ATCIPSTA? 查询ipATCIPMUX0 设置单连接ATCIPSTART"TCP","19…...

Flutter 类似onResume 监听,解决入场动画卡顿

在Flutter 实际开发过程中&#xff0c;页面数据往往是异步加载&#xff0c;接口请求回来后&#xff0c;数据刷新显示到界面上。 由于Flutter性能原因&#xff0c;也可能因为获取数据量比较大&#xff0c;在新页面路由进场动画执行过程中&#xff0c;接口请求结果回来了&#x…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...