如何标记和测量斑点的大小?

2024-01-13

我正在用Python学习图像分析,我只是一个初学者。我能够编写代码(我在下面分享)来检测此纳米颗粒图像中的斑点(纳米颗粒):

我可以使用以下方法检测到有 10 个纳米粒子cv2.connectedComponents,但现在我需要:

  1. 用数字标记每个纳米颗粒以生成最终图像。

  2. 计算组成每个纳米粒子的像素数,以便我可以确定它们的大小。

我尝试四处研究,但找不到任何适合我的东西。有谁愿意帮助我吗?如果你能提出一个代码那就太好了,如果你也能解释它,那就太棒了!

import numpy as np
    import cv2
    from matplotlib import pyplot as plt
    img = cv2.imread('Izzie -  - 0002.tif')

    #show figure using matplotlib
    plt.figure(1)
    plt.subplot(2, 2, 1) # Figure 1 has subplots 2 raws, 2 columns, and this is plot 1
    plt.gca().set_title('Original')
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # , cmap='gray'

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    plt.figure(1)
    plt.subplot(2, 2, 2) # Figure 1 has subplots 2 raw, 2 columns, and this is plot 2
    plt.gca().set_title('Gray')
    plt.imshow(cv2.cvtColor(gray, cv2.COLOR_BGR2RGB)) # , cmap='gray'


# In global thresholding (normal methods), we used an arbitrary chosen value as a threshold
    # In contrast, Otsu's method
    # avoids having to choose a value and determines it automatically.
    #The method returns two outputs. The first is the threshold that was used and the secon
    # output is the thresholded image.

ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

print('Ret = ', ret) # Applies an arbitrary threshold of 128

plt.figure(1)
    plt.subplot(2, 2, 3)
    plt.gca().set_title('Threshold')
    plt.imshow(cv2.cvtColor(thresh, cv2.COLOR_BGR2RGB))


#-------------------------------------------------------------------------------------------
    # MORPHOLOGICAL TRANSFORMATION
    # noise removal using morphological trasnformations
    # For more info see: https://opencv-python
tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html

    # Set up the kernel - structuring element
    kernel = np.ones((3,3), np.uint8) # 3x3 array of 1s of datatype 8-bytes

    # Remove noise using Opening (erosion followed by dilation)
    opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 4)
    plt.figure(2)
    plt.subplot(2, 2, 1)
    plt.gca().set_title('Noise rem')
    plt.imshow(cv2.cvtColor(opening, cv2.COLOR_BGR2RGB))


    # sure background area
    # dilation operation
    sure_bg = cv2.dilate(opening,kernel,iterations=3)

    plt.figure(2)
    plt.subplot(2, 2, 2)
    plt.gca().set_title('Dilated img')
    plt.imshow(cv2.cvtColor(sure_bg, cv2.COLOR_BGR2RGB))



    # Apply a distance transformation to transform the image into a gradient of B&W pixels and detect possible connected objects
    dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)

    plt.figure(2)
    plt.subplot(2, 2, 3) 
    plt.gca().set_title('Dist_transform')
    plt.imshow(cv2.cvtColor(dist_transform, cv2.COLOR_BGR2RGB))



    # Apply a threshold to go back to binary B&W image
    ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(),255,0)
    print('Ret treshold: ', ret)

    plt.figure(2)
    plt.subplot(2, 2, 4) 
    plt.gca().set_title('Threshold')
    plt.imshow(cv2.cvtColor(sure_fg, cv2.COLOR_BGR2RGB))


    # Finding unknown region
    sure_fg = np.uint8(sure_fg) # creates an 8-bit unsigned matrix

    plt.figure(3)
    plt.subplot(1, 2, 1) 
    plt.gca().set_title('Sure_fg')
    plt.imshow(cv2.cvtColor(sure_fg, cv2.COLOR_BGR2RGB))


    unknown = cv2.subtract(sure_bg,sure_fg)

    plt.figure(3)
    plt.subplot(1, 2, 2) 
    plt.gca().set_title('Unknown')
    plt.imshow(cv2.cvtColor(unknown, cv2.COLOR_BGR2RGB))


    #----------------------------------------------------------------------------------------------------------------------#

    # Marker labelling
    # Connected components counts all black objects in the image. For explaination see: https://www.youtube.com/watch?v=hMIrQdX4BkE
    # It gives 2 objects in return, the number of objects and a picture with labelled objects.

n_objects, markers = cv2.connectedComponents(sure_fg)

    plt.figure(4)
    plt.subplot(2, 1, 1) 
    plt.gca().set_title('markers')
    plt.imshow(markers) 


    # Add one to all labels so that sure background is not 0, but 1
    markers = markers+1

    # Now, mark the region of unknown with zero
    markers[unknown==255] = 0


    markers = cv2.watershed(img, markers)
    img[markers == 8] = [255, 0, 0] # Overlay red circles (-1 val) to img. 2, 3, 4 are all the different objects detected in the image

    plt.figure(4)
    plt.subplot(2, 1, 2)
    plt.gca().set_title('markers')
    plt.imshow(img)



    print('Number of particles detected: ', n_objects-2)


    plt.show()

如果您的粒子是(几乎)黑色,请不要使用 Otsu 阈值,而是使用固定值来掩盖(几乎)黑色像素。在逆二值化图像上,您可以应用形态学闭运算(以获取整个粒子)和开运算(以消除背景噪声),请参阅cv2.morphologyEx https://docs.opencv.org/4.1.1/d4/d86/group__imgproc__filter.html#ga67493776e3ad1a3df63883829375201f。之后,你找到所有轮廓以获得粒子和尺度,参见cv2.findContours https://docs.opencv.org/4.1.1/d3/dc0/group__imgproc__shape.html#gadf1ad6a0b82947fa1fe3c3d497f260e0。我们确定所有轮廓的边界矩形,以便在输入图像中的粒子上放置一些标签,并通过将粒子边界框的宽度/高度除以粒子边界框的宽度来计算粒子的水平和垂直直径。比例尺的边界框。

在我的代码中,我省略了几件事,包括 Matplotlib 输出。 (在写作时,我刚刚注意到,您还有更多代码;我没有看到滚动条……我没有看到,也没有合并该代码。)

import cv2
from matplotlib import pyplot as plt
from skimage import io                  # Only needed for web grabbing images, use cv2.imread for local images

# Read image from web; Attention: it's already RGB
img = io.imread('https://i.stack.imgur.com/J46nA.jpg')

# Convert to grayscale; Attention: Source is RGB from web grabbing
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)

# Use fixed threshold to mask black areas
_, thresh = cv2.threshold(gray, 30, 255, cv2.THRESH_BINARY_INV)

# Morphological closing to get whole particles; opening to get rid of noise
img_mop = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7)))
img_mop = cv2.morphologyEx(img_mop, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15)))

# Find contours
cnts, _ = cv2.findContours(img_mop, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# Get bounding rectangles for the scale and the particles
thr_size = 2000
scale = [cv2.boundingRect(cnt) for cnt in cnts if cv2.contourArea(cnt) > thr_size]
particles = [cv2.boundingRect(cnt) for cnt in cnts if cv2.contourArea(cnt) < thr_size]

# Iterate all particles, add label and diameters to input image
for i, p in enumerate(particles):
    x = p[0]
    y = max(0, p[1]-10)
    d_h = p[2] / scale[0][2] * 500
    d_v = p[3] / scale[0][2] * 500
    cv2.putText(img, str(i), (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 2)
    print('Particle ' + str(i) + ' | Horizontal diameter: ' + '{:.2f}'.format(d_h) +
          ' nm, vertical diameter: ' +  '{:.2f}'.format(d_v) + ' nm')

cv2.imshow('img', cv2.resize(img, dsize=(0, 0), fx=0.5, fy=0.5))
cv2.imshow('thresh', cv2.resize(thresh, dsize=(0, 0), fx=0.5, fy=0.5))
cv2.imshow('img_mop',  cv2.resize(img_mop, dsize=(0, 0), fx=0.5, fy=0.5))
cv2.waitKey(0)
cv2.destroyAllWindows()

The thresh具有固定阈值的图像:

The img_mop应用形态学操作后的图像(注意:比例仍然存在,因此我们可以使用它进行尺寸近似):

最后,输入/输出图像ìmg带有相应的标签(由于图像大小限制,此处必须使用 JPG):

最后但并非最不重要的一点是print output:

Particle 0 | Horizontal diameter: 20.83 nm, vertical diameter: 23.03 nm
Particle 1 | Horizontal diameter: 20.83 nm, vertical diameter: 20.83 nm
Particle 2 | Horizontal diameter: 19.74 nm, vertical diameter: 17.54 nm
Particle 3 | Horizontal diameter: 23.03 nm, vertical diameter: 23.03 nm
Particle 4 | Horizontal diameter: 24.12 nm, vertical diameter: 24.12 nm
Particle 5 | Horizontal diameter: 21.93 nm, vertical diameter: 20.83 nm
Particle 6 | Horizontal diameter: 24.12 nm, vertical diameter: 23.03 nm
Particle 7 | Horizontal diameter: 21.93 nm, vertical diameter: 23.03 nm
Particle 8 | Horizontal diameter: 19.74 nm, vertical diameter: 21.93 nm
Particle 9 | Horizontal diameter: 19.74 nm, vertical diameter: 19.74 nm

希望有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何标记和测量斑点的大小? 的相关文章

  • xlrd.biffh.XLRDError:Excel xlsx 文件;不支持[重复]

    这个问题在这里已经有答案了 我正在尝试使用读取启用宏的 Excel 工作表pandas read excel与 xlrd 库 它在本地运行良好 但是当我尝试将其推送到 PCF 时 我收到此错误 2020 12 11T21 09 53 441
  • 切片稀疏(scipy)矩阵

    我将不胜感激任何帮助 以理解从 scipy sparse 包中切片 lil matrix A 时的以下行为 实际上 我想根据行和列的任意索引列表提取子矩阵 当我使用这两行代码时 x1 A list 1 x2 x1 list 2 一切都很好
  • Python 2.7 将比特币私钥转换为 WIF 私钥

    作为一名编码新手 我刚刚完成了教程 教程是这样的 https www youtube com watch v tX XokHf nI https www youtube com watch v tX XokHf nI 我想用 1 个易于阅读
  • boto3 资源(例如 DynamoDB.Table)的类型注释

    The boto3库提供了几种返回资源的工厂方法 例如 dynamo boto3 resource dynamodb Table os environ DYNAMODB TABLE 我想注释这些资源 以便我可以获得更好的类型检查和完成 但我
  • 希伯来语中的稀疏句子标记化错误

    尝试对希伯来语使用稀疏句子标记 import spacy nlp spacy load he doc nlp text sents list doc sents I get Warning no model found for he Onl
  • 如何使用显式引用转储 YAML?

    递归引用非常适合ruamel yaml or pyyaml ruamel yaml dump ruamel yaml load A A id001 id001 然而 它 显然 不适用于普通引用 ruamel yaml dump ruamel
  • 为什么我的代码不能根据字典解码加密字符串?

    我有一本字典 其中包含代表字母的键和值 例如一个简单的 DICT CODE b g n a p o x d t y 我收到了一个加密代码 并将该字符串转换为一个列表 其中每个项目都是一个单词 我需要根据字典中的项目来解决它 代码示例是 wo
  • Tweepy StreamListener 到 CSV

    我是 python 新手 我正在尝试开发一个应用程序 使用 Tweepy 和 Streaming API 从 Twitter 检索数据并将数据转换为 CSV 文件 问题是此代码不会创建输出 CSV 文件 也许是因为我应该将代码设置为在实现例
  • 当单词以“|”分隔时如何读取文件(埃因霍温)?

    在Python中 我有一个文件 其中的单词由 例如 city state zipcode 我的文件阅读器无法区分单词 另外 我希望我的文件阅读器从第 2 行而不是第 1 行开始 如何让我的文件阅读器分隔单词 import os import
  • 更改 python tkinter canvas 中的线坐标

    我画了一条线tkinter Canvas现在我想移动一端 这可能吗 例如和itemconfig import tkinter tk tkinter Tk canvas tkinter Canvas tk canvas pack line c
  • python是带有字符串的运算符行为[重复]

    这个问题在这里已经有答案了 我无法理解以下行为 我正在创建 2 个字符串 并使用 is 运算符来比较它 对于第一种情况 它的工作方式有所不同 对于第二种情况 它按预期工作 当我使用逗号或空格时 它显示是什么原因False与比较is当没有使用
  • 动态 __init_subclass__ 方法的参数绑定

    我正在尝试让类装饰器工作 装饰器会添加一个 init subclass 方法到它所应用的类 但是 当该方法动态添加到类中时 第一个参数不会绑定到子类对象 为什么会发生这种情况 举个例子 这是可行的 下面的静态代码是我试图最终得到的示例 cl
  • 如何使用 sys.path.append 在 Python 中导入文件?

    我的桌面上有两个目录 DIR1 and DIR2其中包含以下文件 DIR1 file1 py DIR2 file2 py myfile txt 这些文件包含以下内容 file1 py import sys sys path append s
  • Python 类型安全吗?

    根据维基百科 https en wikipedia org wiki Type system Type safety and memory safety 如果一种语言不允许违反类型系统规则的操作或转换 计算机科学家就认为该语言是 类型安全的
  • 在 Sphinx 中,有没有办法在声明参数的同时记录参数?

    我更喜欢在声明参数的同一行记录每个参数 根据需要 以便应用D R Y http en wikipedia org wiki Don t repeat yourself 如果我有这样的代码 def foo flab nickers a ser
  • 如何将回溯/sys.exc_info() 值保存在变量中?

    我想将错误名称和回溯详细信息保存到变量中 这是我的尝试 import sys try try print x except Exception ex raise NameError except Exception er print 0 s
  • 对数据帧的每 2 小时数据进行 Groupby

    我有一个数据框 Time T201FN1ST2010 T201FN1VT2010 1791 2017 12 26 00 00 00 854 69 0 87 1792 2017 12 26 00 20 00 855 76 0 87 1793
  • 更改 Python Cmd 模块处理自动完成的方式

    我有一个 Cmd 控制台 设置为自动完成 Magic the Gathering 收藏管理系统的卡牌名称 它使用文本参数在数据库中查询卡片 并使用结果自动完成 建议卡片 然而 这些卡片名称有多个单词 Cmd 会从last到行尾的空间 例如
  • python sklearn中的fit方法

    我问自己关于 sklearn 中拟合方法的各种问题 问题1 当我这样做时 from sklearn decomposition import TruncatedSVD model TruncatedSVD svd 1 model fit X
  • 使用 urllib 编码时保持 url 参数有序

    我正在尝试用 python 模拟 get 请求 我有一个参数字典 并使用 urllib urlencode 对它们进行 urlencode 我注意到虽然字典的形式是 k1 v1 k2 v2 k3 v3 urlencoding 后参数的顺序切

随机推荐

  • if语句与if-else语句,哪个更快?

    前几天我和一个朋友争论了这两个片段 哪个更快 为什么 value 5 if condition value 6 and if condition value 6 else value 5 What if value是一个矩阵 注 我知道va
  • 如何在 Objective C 中编写正则表达式(NSRegularExpression)?

    当我在 PHP 中测试这个正则表达式时 它可以工作 但它在 Objective C 中不起作用 www a zA Z0 9 2 63
  • gnome 终端控制键上的 emacs

    I m running emacs on a terminal mode no window system emacs nw I ve few global keys defined in emacs like C C x C C etc
  • Three.js:如何将场景的 2D 快照制作为 JPG 图像?

    我有一个如下所示的 Three js 场景 var scene new THREE Scene var camera new THREE PerspectiveCamera 75 window innerWidth window inner
  • 符号|查看 Flask 教程

    我正在为 Flask 框架编写一个教程 网址为http blog miguelgrinberg com post the flask mega tutorial part iii web forms http blog miguelgrin
  • Android 6.0 权限变更回调

    我想知道当用户在 Android 6 0 上更改应用程序设置中的权限时是否有某种方式可以收到通知 我一直在寻找这个答案 但没有运气 您知道广播接收器和某些特定意图是否可能吗 或者也许有一些黑客可以实现这一目标 根据这个答案 https st
  • 在开发、登台和生产之间同步 Drupal 站点

    通常在 Drupal 6 x 站点启动后 我会让人们开始注册并输入他们自己的内容 每当需要升级时 生产中的数据库都会复制到开发版 然后在开发版上完成开发 然后推送到登台以供客户批准 当网站最终准备上线时 出现了一个问题 生产服务器具有最新的
  • 为什么 ng-scope 添加到我的部分视图的 javascript 内联中并使警报不起作用?

    我正在使用 AngularJs 和模板系统 我想向每个模板添加特定的内联 javascript 脚本 添加与所选选项卡相关的警报框 主页 列表 设置 Html 渲染 但是添加了 ng scope 并且当您更改选项卡时没有任何警报 我在这里提
  • jQuery datepicker altFormat 不显示

    我有一个 jQuery 日期选择器 它根据卖家的语言偏好进行本地化 每个日期选择器自定义都有不同的日期格式 但我希望提交表单时的输入采用特定的格式进行解析 我尝试在日期选择器上使用 altFormat 将其设置为 mm dd yy 但我不希
  • 角度 ui-router 维护选项卡之间的状态

    想知道保留选项卡之间状态的最佳方法 我使用引导选项卡和角度用户界面路由器 我在其中一个选项卡中有一个谷歌地图 并且不想在用户选择该选项卡时重新加载地图 请指教 Thanks 我认为本期讨论了您正在寻找的内容 https github com
  • php mysql asc/desc 顺序

    TABLE timeslot id timeslot times 1 09 00 2 09 30 3 10 00 4 10 30 5 11 00 bookslot id id timeslot date b ref 1 2 2010 02
  • 如何让Android模拟器启动更快

    我目前一直坚持使用 Atom CPU 桌面来开发 Android 应用程序 有哪些方法可以改善其启动时间 运行模拟器时 我可以看到模拟器使用的核心数量只有一个 我从 Eclipse ADT 插件中运行模拟器 如何让模拟器使用两个核心而不是一
  • 只需单击标签即可双击

    我有一个标签 并且单击它时正在运行一些功能 但是 当单击事件发生时 双击事件完成 然后我的函数运行两次 你可以看一个简单的例子here http jsfiddle net vgWGT 2 HTML
  • iOS 7 master有导航栏提示时的细节布局

    我在 iOS 7 中遇到布局问题 要重现 请创建一个简单的主从应用程序并将此行插入MasterViewController m self navigationItem prompt Master 这在DetailViewController
  • 正则表达式允许非 ASCII 和外文字母吗?

    是否可以创建一个正则表达式来允许非ascii字母与拉丁字母一起使用 例如中文或希腊符号 例如允许A汉语AbN汉语 我目前有以下内容 w d w d s 只允许使用拉丁字母 In NET p L d p L d s 相当于你的正则表达式 另外
  • Angular2 5 分钟安装错误 - 未定义需求

    我正在做Angular2 5 分钟快速入门 https angular io docs ts latest quickstart html 现在教程已经进行了大约一半 我已经正确设置了以下文件 索引 html 应用程序组件 ts 应用程序
  • 实现观察者模式时出现的问题:“成员引用基类型 ________ 不是结构或联合”

    我一直在实现一个准系统观察者模式 但遇到了一个有点神秘的错误 成员引用基类型 Observer 不是结构或联合 我认为这与我使用模板有关 但我仍然对模板感到相当不舒服 这是有问题的代码 为了简化事情而删除了大多数 cons 析构函数 主题界
  • 在Android中绘画时如何遮盖一个简单的区域?

    下面是一个简化的描述 想象一下 我有一个 View 类 它可以绘制一面墙的图片 并且我想在绘制它时切出一个窗口 假设我扩展该 View 类并重写其dispatchDraw 方法来执行以下操作 首先绘制背景 如果有的话 可以通过窗户看到 接下
  • 有没有办法像oracle中的rownum一样获取Mysql中的行号[重复]

    这个问题在这里已经有答案了 有没有办法像oracle中的rownum一样获取Mysql中的行号 如果没有那么有什么间接的方法吗 请建议 直到MySQL终于支持现代SQL http modern sql com slides 获得类似内容的唯
  • 如何标记和测量斑点的大小?

    我正在用Python学习图像分析 我只是一个初学者 我能够编写代码 我在下面分享 来检测此纳米颗粒图像中的斑点 纳米颗粒 我可以使用以下方法检测到有 10 个纳米粒子cv2 connectedComponents 但现在我需要 用数字标记每