工作流程来比较两个图像中的重叠?

我将不得不提前为这个问题的模糊性而道歉。 我期待着帮助一位正试图比较两幅图像中荧光神经重叠的朋友。

设置如下:有一张以红色标记的神经和背景图像,以绿色标记的神经和背景图像相同。 有些神经只用红色标记,有些只用绿色标记,这很重要。 我们想要做的是覆盖红色图像和绿色图像,然后找出哪个神经与两个标签(红色和绿色重叠)。

对于两个标签都有一个连续的强度(所以有明显的红色和暗淡的红色斑点线条,绿色也是如此)。

我在想你可以做的是为红色设置一个阈值强度,并且只用那些达到阈值强度的神经重新绘制图像。 你也可以为绿色做这个。 然后,通过测量一个输出中另一个输出中发现的神经组织的百分比,可以通过输出比较重叠神经的比例。

在重叠区域可以被着色(例如蓝色)的情况下,能够生成输出图像是理想的。 然后,我们可以在所有重叠部分都是蓝色的情况下获取该输出,并将其覆盖在原始红色/绿色图像上,以突出显示重叠的神经。

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

这些都远远超出了我的技能水平^ _ ^;

如果有人认为这是可能的,对于更好的工作流程有任何建议,或者可以指向我一些好的阅读或包的方向来解决这个问题,这将是非常感激。

谢谢你尽你所能的帮助!

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

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


我一直在学习一些免费的OSX,Linux和Windows可用的OpenCV 。 我认为它可能会为你的问题增加一些交互性,所以我已经实现了与我在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;
}

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


正如@JanEglinger所说,没有必要使用(或付费)Matlab,特别是如果你的编程技巧有限。

我会建议ImageMagick免费并安装在大多数Linux发行版上,并且也可以从这里用于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%,你会得到这个:

链接地址: http://www.djcxy.com/p/67297.html

上一篇: Workflow to compare the overlap in two images?

下一篇: easy way to add an oriented stripe to an image