OpenCV-Java-如何删除集群周围的一些像素
我正在做一个项目,我需要确定图像的某些区域。在处理图像并去除所有不必要的东西后,我最终得到了如图所示的区域(绿色圆圈内的区域) 我无法使用OpenCV在该区域周围绘制圆。我目前正在使用OpenCV的Java版本。如果有人能给我指出如何在图像上实现绿色圆圈的正确方向,这将非常有帮助 我试图探测到的东西。 blob探测器-没有取得多大成就。 集群-与blob检测器相同。 HoughCircles-在图像中绘制不必要的圆。 FindContour-没有画任何东西,因为它不是一个完美的圆、椭圆或任何其他众所周知的多边形 我感谢你的帮助 这里有一个解决方案:OpenCV-Java-如何删除集群周围的一些像素,java,opencv,image-processing,Java,Opencv,Image Processing,我正在做一个项目,我需要确定图像的某些区域。在处理图像并去除所有不必要的东西后,我最终得到了如图所示的区域(绿色圆圈内的区域) 我无法使用OpenCV在该区域周围绘制圆。我目前正在使用OpenCV的Java版本。如果有人能给我指出如何在图像上实现绿色圆圈的正确方向,这将非常有帮助 我试图探测到的东西。 blob探测器-没有取得多大成就。 集群-与blob检测器相同。 HoughCircles-在图像中绘制不必要的圆。 FindContour-没有画任何东西,因为它不是一个完美的圆、椭圆或任何其他
注意:如果您想完美地保留图案,可以通过重建(侵蚀+测地线重建)将洞口替换为洞口。我终于找到了解决问题的方法。我使用了OpenCV库中的特征检测器,并为检测器设置了正确的阈值。这对我起了作用。Java中的代码如下所示
public static void main(String[] args){
try{
//Validation whether a file name is passed to the function
if(args.length == 0){
System.out.println("here...");
log.error("No file was passed to the function");
throw new IOException();
}
//Read the image from the input
Mat inputMat = Highgui.imread(args[0],Highgui.CV_LOAD_IMAGE_GRAYSCALE);
//Create a feature detector. In this case we are using SURF (Speeded-Up Robust Features) detector.
MatOfKeyPoint objectKeyPoints = new MatOfKeyPoint();
FeatureDetector featureDetector = FeatureDetector.create(FeatureDetector.SURF);
//A temporary file is created to input Hessian Threshold to the SURF detector
File tempFile = File.createTempFile("config", ".yml");
String settings = "%YAML:1.0\nhessianThreshold: 7000.\noctaves: 3\noctaveLayers: 4\nupright: 0\n";
FileWriter writer = new FileWriter(tempFile, false);
writer.write(settings);
writer.close();
//Read the configuration from the temporary file to assign the threshold for the detector
featureDetector.read(tempFile.getPath());
//Detect the features in the image provided
featureDetector.detect(inputMat, objectKeyPoints);
//Iterate through the list of key points detected in the previous step and find the Key Point with the largest size
List<KeyPoint> objectKeyPointList = objectKeyPoints.toList();
KeyPoint impKeyPoint = new KeyPoint();
for(int i=0; i<objectKeyPointList.size(); i++){
if(impKeyPoint == null){
impKeyPoint = objectKeyPointList.get(i);
}
else if(impKeyPoint.size < objectKeyPointList.get(i).size){
impKeyPoint = objectKeyPointList.get(i);
}
}
//If the size of the Key Point is greater than 120 then reduce the size to 120 and if the size is less than 120 then increase to 120
if(impKeyPoint.size > 120){
KeyPoint tempKeyPoint = new KeyPoint();
tempKeyPoint = impKeyPoint;
tempKeyPoint.size = 120;
impKeyPoint = tempKeyPoint;
}
else if(impKeyPoint.size < 120){
KeyPoint tempKeyPoint = new KeyPoint();
tempKeyPoint = impKeyPoint;
tempKeyPoint.size = 120;
impKeyPoint = tempKeyPoint;
}
//Convert the Key Point to MatOfKeyPoint since drawKeyPoints accepts only MatOfKeyPoint
MatOfKeyPoint impMatOfKeyPoint = new MatOfKeyPoint(impKeyPoint);
//Mat for drawing the circle in the image
Mat outputImage = new Mat(inputMat.rows(), inputMat.cols(), Highgui.CV_LOAD_IMAGE_COLOR);
//Green color for the circle
Scalar greenCircle = new Scalar(0, 255, 0);
//Draw the circle around the optic nerve when detected
Features2d.drawKeypoints(inputMat, impMatOfKeyPoint, outputImage, greenCircle, Features2d.DRAW_RICH_KEYPOINTS);
//Write the image to a file
Highgui.imwrite("surf_keypoints.png", outputImage);
}catch(Exception e){
log.fatal(e.getMessage());
}
}
publicstaticvoidmain(字符串[]args){
试一试{
//验证是否将文件名传递给函数
如果(args.length==0){
System.out.println(“此处…”);
log.error(“没有向函数传递任何文件”);
抛出新IOException();
}
//从输入中读取图像
Mat inputMat=Highgui.imread(args[0],Highgui.CV\u LOAD\u IMAGE\u GRAYSCALE);
//创建一个特征检测器。在这种情况下,我们使用的是SURF(加速鲁棒特征)检测器。
MatOfKeyPoint objectKeyPoints=新的MatOfKeyPoint();
FeatureDetector FeatureDetector=FeatureDetector.create(FeatureDetector.SURF);
//创建一个临时文件,将Hessian阈值输入到冲浪检测器
File tempFile=File.createTempFile(“config”,“.yml”);
String settings=“%YAML:1.0\n高级管理员:7000。\n管理员:3\n管理员:4\n优先级:0\n”;
FileWriter writer=新的FileWriter(tempFile,false);
writer.write(设置);
writer.close();
//从临时文件中读取配置,为探测器分配阈值
读取(tempFile.getPath());
//检测所提供图像中的特征
特征检测器。检测(inputMat、objectKeyPoints);
//迭代上一步中检测到的关键点列表,并找到大小最大的关键点
List objectKeyPointList=objectKeyPoints.toList();
KeyPoint impKeyPoint=新的KeyPoint();
对于(int i=0;i 120){
KeyPoint tempKeyPoint=新的KeyPoint();
tempKeyPoint=impKeyPoint;
tempKeyPoint.size=120;
impKeyPoint=tempKeyPoint;
}
否则如果(impKeyPoint.size<120){
KeyPoint tempKeyPoint=新的KeyPoint();
tempKeyPoint=impKeyPoint;
tempKeyPoint.size=120;
impKeyPoint=tempKeyPoint;
}
//将关键点转换为MatOfKeyPoint,因为drawKeyPoints仅接受MatOfKeyPoint
MatOfKeyPoint impMatOfKeyPoint=新的MatOfKeyPoint(impKeyPoint);
//用于在图像中绘制圆的垫子
Mat outputImage=新Mat(inputMat.rows(),inputMat.cols(),Highgui.CV\u LOAD\u IMAGE\u COLOR);
//圆圈的绿色
标量绿圈=新标量(0,255,0);
//检测到时,在视神经周围画一个圆圈
功能2d.绘制关键点(inputMat、impMatOfKeyPoint、outputImage、绿色圆圈、功能2d.绘制丰富的关键点);
//将图像写入文件
imwrite(“surf_keypoints.png”,outputImage);
}捕获(例外e){
log.fatal(如getMessage());
}
}
希望这对其他人有帮助。谢谢您的回复。我可以做第一步。我尝试了第2步,如果连接的组件是2次通过,则需要花费大量时间来处理。你有一些例子的链接,我可以让它更快吗?这是一个链接,指向用Java开发的Union Find算法的法语页面,但是用C++重新实现它非常容易:我将在我的项目中实现它,并让您知道会发生什么。非常感谢。