【问题标题】:Workflow to compare the overlap in two images?比较两个图像中重叠的工作流程?
【发布时间】:2017-08-22 00:36:37
【问题描述】:

我将不得不提前为这个问题的含糊之处道歉。我希望帮助一位尝试比较两张图像中荧光神经重叠的朋友。

设置如下: 有一张神经和背景的图像用红色标记,同样的神经和背景图像用绿色标记。有些神经只用红色标记,有些只用绿色标记,这很重要。我们要做的是叠加红色图像和绿色图像,然后找出两者都标记的神经(红色和绿色重叠的地方)。

两个标签的强度是连续的(因此有明亮的明显红色线条和暗淡的红色斑点区域,绿色也一样)。

我在想你能做的就是为红色设置一个阈值强度,然后只用那些满足该阈值强度的神经重新绘制图像。您也可以为绿色执行此操作。然后,您可以通过输出在另一个输出中找到的神经组织百分比来比较重叠神经的比例。

最好能够生成重叠区域可以着色(例如蓝色)的输出图像。然后,我们可以将所有重叠部分都是蓝色的输出作为输出,并将其覆盖在原始的红/绿图像上,以在视觉上突出显示重叠的神经。

或者(或组合),您可以将图像转换为字符串,然后在这些字符串中的相同位置查找匹配的字符。

这两个都远远超出了我的水平^_^;

如果有人认为这是可能的,对更好的工作流程有任何建议,或者可以为我指出一些好的阅读或解决方案的方向,将不胜感激。

感谢您提供的任何帮助!

编辑:Matlab 中的这个建议回答了我认为的问题的开始(如何测量哪些像素超过了某个阈值强度)。它们转换为灰度,然后寻找发白像素的强度。然后,我需要生成满足该阈值强度的像素的输出。

http://www.mathworks.com/matlabcentral/answers/86484-how-to-find-the-intensity-of-each-pixel-of-an-image

【问题讨论】:

  • 提供示例图片。您可能需要先解决注册问题,即图像之间的所有内容是否正确排列。
  • 这里是两张图片的例子。您可以看到看起来像箭头的神经分支在红色和绿色中重叠。 img1:img.photobucket.com/albums/v228/markh1822/…img2:img.photobucket.com/albums/v228/markh1822/…
  • 获取两个图像的阈值然后将它们加在一起的方法应该可以正常工作。或者,由于您有一个红色图像和另一个绿色图像,您可以组合颜色以获得红绿色洋红色图像,洋红色将是重叠强烈的地方。
  • 这是我们开始的计划。但不幸的是,红色上的绿色看起来并不是很显眼。玩弄透明胶片和不同的颜色,它并没有给人留下它需要的印象。大多数时候,绿色淹没了红色。有关于代码的建议或在哪里寻找图像处理中的代码建议?感谢您的回复!
  • 按照您提供的链接中的步骤获取阈值图像。制作一个新图像,其中全零为黑色,1 个红色为红色,1 个绿色为绿色,红色和绿色都设置为蓝色,对比度应该没问题。 Matlab 的图像处理工具箱非常好,提供了大量示例,让您走上正轨。

标签: image matlab image-processing


【解决方案1】:

正如@JanEglinger 所建议的,无需使用(或付费)Matlab,尤其是在您的编程技能有限的情况下。

我会推荐 ImageMagick,它是免费的,可以安装在大多数 Linux 发行版上,也可以从here 获得用于 OSX 和 Windows 的。然后,您可以从命令行完成您想做的事情,无需编译器或开发环境和陡峭的学习曲线。

让我们先来看看你的红色图像,只需在终端中使用命令行,我们可以这样查看统计信息:

identify -verbose red.jpg | more

Image: red.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: DirectClass
  Geometry: 100x100+0+0
  Resolution: 72x72
  Print size: 1.38889x1.38889
  Units: PixelsPerInch
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    Pixels: 10000
    Red:
      min: 8 (0.0313725)
      max: 196 (0.768627)                                 <--- Good stuff in Red channel
      mean: 46.1708 (0.181062)
      standard deviation: 19.4835 (0.0764057)
    Green:
      min: 0 (0)
      max: 13 (0.0509804)                                 <--- Nothing much in Green channel
      mean: 3.912 (0.0153412)
      standard deviation: 1.69117 (0.00663204)
    Blue:
      min: 0 (0)
      max: 23 (0.0901961)                                 <--- Nothing much in Blue channel
      mean: 4.3983 (0.0172482)
      standard deviation: 2.88733 (0.0113229)

并且看到在红色频道之外几乎没有任何用途的信息。因此,我们可以将其分成红色、绿色和蓝色 3 个通道,并像这样丢弃绿色和蓝色通道:

convert red.jpg -separate -delete 1,2 justRed.jpg

这给了我们这个

虽然对比度不是很好,因为它的范围只有 8-196 而不是 0-255,所以我们可以将其标准化为全范围,然后像这样将阈值设为 50%:

convert red.jpg -separate -delete 1,2 -normalize -threshold 50% r.jpg

这给出了这个:

如果我们现在想为您的绿色图像做同样的事情,我们会这样做,但这次删除红色和蓝色通道:

convert green.jpg -separate -delete 0,2 -normalize -threshold 50% g.jpg

给出这个:

最后,我们将分离、归一化、阈值化的红色和绿色合成一个相同大小的空蓝色通道,并将它们放在一起作为新图像的红色、绿色和蓝色通道:

convert r.jpg g.jpg -size 100x100 xc:black -combine result.jpg

这为我们提供了我们在 黄色 区域中看到的亮红色和绿色区域。

整个过程实际上只是在终端中输入 3 行代码:

convert red.jpg   -separate -delete 1,2 -normalize -threshold 50% r.jpg
convert green.jpg -separate -delete 0,2 -normalize -threshold 50% g.jpg
convert r.jpg g.jpg -size 100x100 xc:black -combine result.jpg

如果你喜欢这种方法,你可以改变百分比,你可以引入降噪,实际上也可以在一个没有中间文件的更复杂的命令中完成所有工作。无论如何,我向你推荐 ImageMagick,即使你必须使用 Matlab,也许 ImageMagick 中的这个例子会给你一些工作流程的指针。

额外的例子...如果您将红色通道的阈值设置得较低,您将在输出文件中获得更多的红色像素,因此如果您将红色阈值更改为 30%,您将得到:

【讨论】:

    【解决方案2】:

    我一直在学习一些OpenCV,它是免费的,可用于 OSX、Linux 和 Windows。我认为它可能会为您的问题增加一些交互性,所以我实现了与 ImageMagick 中完全相同的算法,但在我的初学者OpenCV 中。如果任何更有经验的人对我的代码有任何建设性的指导方针,我会全力以赴。

    不管怎样,运行时它看起来像这样,你滑动阈值滑块:

    代码如下:

    ////////////////////////////////////////////////////////////////////////////////
    // NerveView.cpp
    // Mark Setchell
    //
    // OpenCV program that takes two images as parameters, the first the red 
    // fluorescent nerve image and the second which is the green image.
    //
    // The two images are resized, normalised and then displayed merged into a 
    // single RGB image where the thresholds on red and green are controlled by
    // sliders. Common areas therefore appear in yellow. Move either slider left
    // to lower the threshold and therefore include more of that colour in the 
    // combined output image, or move slider right to decrease amount of that
    // colour.
    //
    // Run with:
    //
    // ./NerveView red.jpg green.jpg
    //
    // Compile with:
    //
    // g++ `pkg-config --cflags --libs opencv` NerveView.cpp -o NerveView
    //
    ////////////////////////////////////////////////////////////////////////////////
    
    #include <sstream>
    #include <string>
    #include <iostream>
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include <opencv/cv.h>
    #include <opencv/highgui.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    using namespace std;
    using namespace cv;
    
    int main(int argc, char** argv) {
    
        // Temp workspace
        Mat tmp1,tmp2;
    
        // Image size
        Size size(640,480);
    
        // Create a window for controls
        namedWindow("Controls", CV_WINDOW_NORMAL);
        resizeWindow("Controls",640,100);
    
        // Create slider to change Red threshold
        int RedThreshold = 50;
        createTrackbar("Red Threshold Percentage", "Controls", &RedThreshold, 100);
    
        // Create slider to change Green threshold
        int GreenThreshold = 50;
        createTrackbar("Green Threshold Percentage", "Controls", &GreenThreshold, 100);
    
        // Create variables to store input images and load them
        Mat Red,Green;
        Mat planes[3];
    
        // Load red image, split, discard G & B, resize, normalize
        tmp1   = imread(argv[1], CV_LOAD_IMAGE_COLOR);
        split(tmp1,planes);
        resize(planes[2],tmp1,size);
        normalize(tmp1,Red,0,255,NORM_MINMAX,CV_8UC1);
    
        // Load green image, split, discard R & B, resize, normalize
        tmp1   = imread(argv[2], CV_LOAD_IMAGE_COLOR);
        split(tmp1,planes);
        resize(planes[1],tmp1,size);
        normalize(tmp1,Green,0,255,NORM_MINMAX,CV_8UC1);
    
        // Make empty Blue channel, same size
        Mat Blue=Mat::zeros(size,CV_8UC1);
    
        //Create window to display images
        cv::namedWindow("Image", CV_WINDOW_AUTOSIZE);
    
        // Create variable to store the processed image
        Mat img=Mat::zeros(640,480,CV_8UC3);
    
        while (true){
    
        // Get thresholds, apply to their channels and combine to form result
            threshold(Red,tmp1,(RedThreshold*255)/100,255,THRESH_BINARY);
            threshold(Green,tmp2,(GreenThreshold*255)/100,255,THRESH_BINARY);
    
            // Combine B, G and R channels into "img"
            vector<Mat> channels;
            channels.push_back(Blue);
            channels.push_back(tmp2);
            channels.push_back(tmp1);
            merge(channels,img);
    
            // Display result
            imshow("Image",img);
    
            // See if user pressed a key
            int key=cvWaitKey(50);
            if(key>=0)break;
        }
        return 0;
    }
    

    关键词:神经、神经、荧光

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-26
      • 2012-04-04
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多