Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 分割后如何去除图像中的小物体_Java_Android_Opencv_Image Processing_Feature Extraction - Fatal编程技术网

Java 分割后如何去除图像中的小物体

Java 分割后如何去除图像中的小物体,java,android,opencv,image-processing,feature-extraction,Java,Android,Opencv,Image Processing,Feature Extraction,说明 我有一张肺癌CT扫描图像,我想从中分割和提取癌区。我使用了opencv和Java 我有以下图像作为输入: 在使用阈值分割和分水岭方法进行分割后,我得到以下结果: 然后,我想从分割的图像中提取癌区,所以我必须去除所有噪声和感兴趣区域(癌结节)之外的其他物体。如下图所示,我想像这样提取癌结节: 如何在android中使用OpenCV实现这一点 为什么不使用称为MobileUnit的深层神经网络来解决语义分割问题。我刚才提到它有一个非常简单的设计。它可用于IOS和Android 您可以在G

说明

我有一张肺癌CT扫描图像,我想从中分割和提取癌区。我使用了opencv和Java

我有以下图像作为输入:

在使用阈值分割和分水岭方法进行分割后,我得到以下结果:

然后,我想从分割的图像中提取癌区,所以我必须去除所有噪声和感兴趣区域(癌结节)之外的其他物体。如下图所示,我想像这样提取癌结节:


如何在android中使用OpenCV实现这一点

为什么不使用称为MobileUnit的深层神经网络来解决语义分割问题。我刚才提到它有一个非常简单的设计。它可用于IOS和Android

您可以在Github存储库中查看更多详细信息。
为什么不使用称为MobileUnit的深层神经网络来解决语义分割问题。我刚才提到它的设计非常简单。它可用于IOS和Android

您可以在Github存储库中查看更多详细信息。
我试图实施我建议的解决方案。我的答案是C++,但是这个想法很简单,你应该能够用java实现它。正如我所评论的,这个想法是使用形态学来获得感兴趣的斑点。主要是侵蚀操作。让我们看看:

   //Read input image:
   std::string imagePath = "C://opencvImages//lungsImage.png";
   cv::Mat imageInput= cv::imread( imagePath );

   //Convert it to grayscale:
   cv::Mat grayImg;
   cv::cvtColor( imageInput, grayImg, cv::COLOR_BGR2GRAY );
第一步是获得二值图像。看来你实现了分水岭分割。没关系。我试着用一个大窗口应用一个简单的自适应阈值(
601
,在这种情况下)。它给了我很好的结果:

    //Get the binary image:
    cv::adaptiveThreshold( grayImg, grayImg, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 601, 10 );
这是您得到的结果:

现在,有多个斑点。然而,我将寻找最大的blob,因为这是我们感兴趣的目标区域所在的位置。搜索二值图像中最大的斑点是我经常执行的任务,因此我为此准备了一个函数。它被称为
findBiggestBlob
。稍后我将介绍该函数。查看过滤掉较小斑点后得到的结果:

    //Get the biggest blob in the binary image
    cv::Mat targetBlobs = findBiggestBlob( grayImg );
结果是:

现在,只需应用形态学。首先,一个侵蚀操作。使用大小为
5 x 5
ellipse
结构元素和
4
迭代来分离感兴趣的blob:

    //Apply erosion to the biggest blob mask;
    cv::Mat morphKernel = cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size(5, 5) );
    int morphIterations = 4; // use 4 iterations
    cv::morphologyEx( targetBlobs, targetBlobs, cv::MORPH_ERODE, morphKernel, cv::Point(-1,-1), morphIterations );
查看结果,感兴趣的blob现在已分离:

现在,想法很简单。如果我们再次提取图像中最大的斑点,我们最终应该得到的是没有癌区的肺。然后,将此图像减去“分离”的遮罩,我们将在一个遮罩中得到感兴趣的斑点:

    //Get the lungs image:
    cv::Mat bigBlob = findBiggestBlob( targetBlobs );
你得到这个:

现在,让我们应用
explate
操作恢复blob的原始大小,使用相同的结构元素和相同的迭代次数。结果是:

下面是覆盖在原始图像上的斑点(红色):

这是
findBiggestBlob
函数的代码。其思想就是计算二进制输入中的所有轮廓,计算它们的面积,并存储具有束中最大面积的轮廓:

//Function to get the largest blob in a binary image:
cv::Mat findBiggestBlob( cv::Mat &inputImage ){

    cv::Mat biggestBlob = inputImage.clone();

    int largest_area = 0;
    int largest_contour_index=0;

    std::vector< std::vector<cv::Point> > contours; // Vector for storing contour
    std::vector<cv::Vec4i> hierarchy;

    // Find the contours in the image
    cv::findContours( biggestBlob, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); 

    for( int i = 0; i< (int)contours.size(); i++ ) {            

        //Find the area of the contour            
        double a = cv::contourArea( contours[i],false);
        //Store the index of largest contour:
        if( a > largest_area ){
            largest_area = a;                
            largest_contour_index = i;
        }

    }

    //Once you get the biggest blob, paint it black:
    cv::Mat tempMat = biggestBlob.clone();
    cv::drawContours( tempMat, contours, largest_contour_index, cv::Scalar(0),
                  CV_FILLED, 8, hierarchy );

    //Erase the smaller blobs:
    biggestBlob = biggestBlob - tempMat;
    tempMat.release();
    return biggestBlob;
}
//获取二进制图像中最大blob的函数:
cv::Mat findBiggestBlob(cv::Mat和inputImage){
cv::Mat biggestBlob=inputImage.clone();
int最大面积=0;
int最大轮廓指数=0;
std::vector轮廓;//用于存储轮廓的向量
向量层次;
//找到图像中的轮廓
cv::findContours(大网格、等高线、层次结构、cv_RETR_CCOMP、cv_CHAIN_APPROX_SIMPLE);
对于(int i=0;i<(int)等高线.size();i++{
//找到轮廓的区域
双a=cv::轮廓面积(轮廓[i],假);
//存储最大轮廓的索引:
如果(a>最大面积){
最大面积=a;
最大等高线指数=i;
}
}
//一旦得到最大的斑点,将其涂成黑色:
cv::Mat tempMat=biggestBlob.clone();
cv::drawContours(tempMat,等高线,最大等高线索引,cv::Scalar(0),
CV_填充,8,层次结构);
//清除较小的斑点:
biggestBlob=biggestBlob-tempMat;
tempMat.release();
返回最大的blob;
}

我尝试实施我建议的解决方案。我的答案是C++,但是这个想法很简单,你应该能够用java实现它。正如我所评论的,这个想法是使用形态学来获得感兴趣的斑点。主要是侵蚀操作。让我们看看:

   //Read input image:
   std::string imagePath = "C://opencvImages//lungsImage.png";
   cv::Mat imageInput= cv::imread( imagePath );

   //Convert it to grayscale:
   cv::Mat grayImg;
   cv::cvtColor( imageInput, grayImg, cv::COLOR_BGR2GRAY );
第一步是获得二值图像。看来你实现了分水岭分割。没关系。我试着用一个大窗口应用一个简单的自适应阈值(
601
,在这种情况下)。它给了我很好的结果:

    //Get the binary image:
    cv::adaptiveThreshold( grayImg, grayImg, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 601, 10 );
这是您得到的结果:

现在,有多个斑点。然而,我将寻找最大的blob,因为这是我们感兴趣的目标区域所在的位置。搜索二值图像中最大的斑点是我经常执行的任务,因此我为此准备了一个函数。它被称为
findBiggestBlob
。稍后我将介绍该函数。查看过滤掉较小斑点后得到的结果:

    //Get the biggest blob in the binary image
    cv::Mat targetBlobs = findBiggestBlob( grayImg );
结果是:

现在,只需应用形态学。首先,一个侵蚀操作。使用大小为
5 x 5
ellipse
结构元素和
4
迭代来分离感兴趣的blob:

    //Apply erosion to the biggest blob mask;
    cv::Mat morphKernel = cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size(5, 5) );
    int morphIterations = 4; // use 4 iterations
    cv::morphologyEx( targetBlobs, targetBlobs, cv::MORPH_ERODE, morphKernel, cv::Point(-1,-1), morphIterations );
查看结果,感兴趣的blob现在已分离:

现在,想法很简单。如果我们再次提取图像中最大的斑点,我们最终应该得到的是没有癌区的肺。然后,将此图像减去“分离”的遮罩,我们将在一个遮罩中得到感兴趣的斑点:

    //Get the lungs image:
    cv::Mat bigBlob = findBiggestBlob( targetBlobs );
你明白了吗