JavaCV findContours 勾勒图像而不是寻找轮廓
JavaCV findContours outlining the image instead of finding the contour
我正在尝试查找我感兴趣的区域内是否存在 rectangle/square。这是我到目前为止所取得的成就。
下面是我使用 JavaCV 从原始图像中截取的感兴趣区域。
Mat areaOfInterest = OpenCVUtils.getRegionOfInterest("image.jpg",295,200,23,25);
public static Mat getRegionOfInterest(String filePath , int x, int y, int width, int height){
Mat roi = null;
try{
Mat image = Imgcodecs.imread(filePath);
Rect region_of_interest= new Rect(x,y,width,height);
roi = image.submat(region_of_interest);
}catch (Exception ex){
}
return roi;
}
现在我试图找出感兴趣的区域中是否存在任何矩形。我也使用以下代码行来检测它。
Mat gray = new Mat();
Mat binary = new Mat();
Mat hierarchy = new Mat();
ArrayList<MatOfPoint> contours = new ArrayList<>();
cvtColor(image,gray,COLOR_BGR2GRAY);
Core.bitwise_not(gray,binary);
findContours(binary,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE);
if(contours.size() > 0){
for (MatOfPoint contour:contours) {
Rect rect = boundingRect(contour);
/// x = 0, y = 1 , w = 2, h =3
Point p1 = new Point(rect.x,rect.y);
Point p2 = new Point(rect.width + rect.x, rect.height+rect.y);
rectangle(image,p1,p2,new Scalar(0,0,255));
Imgcodecs.imwrite("F:\rect.png",image);
}
}
但是它没有找到图像内部的正方形,而是如下所示勾勒出图像的各个部分。
如果有人能将我推向正确的方向,那就太好了。
OpenCV 的 findContours()
将输入图像视为二值图像,其中所有为 0 的都是黑色,任何 >0 的像素都是白色。由于您正在读取 jpg
图像,压缩使得大多数白色像素不完全是白色,大多数黑色像素也不完全是黑色。因此,如果您有这样的输入图像:
3 4 252 250 3 1
3 3 247 250 3 2
3 2 250 250 2 2
4 4 252 250 3 1
3 3 247 250 3 2
3 2 250 250 2 2
然后 findContours()
将勾勒出整个事情的轮廓,因为它等同于所有 255(它们都 > 0)。
您需要做的就是用 threshold()
或 inRange()
之类的东西对图像进行二值化,这样您的图像实际上就会变成
0 0 255 255 0 0
0 0 255 255 0 0
0 0 255 255 0 0
0 0 255 255 0 0
0 0 255 255 0 0
0 0 255 255 0 0
那么你就可以正确地得到中心的 255 块的轮廓了。
我正在尝试查找我感兴趣的区域内是否存在 rectangle/square。这是我到目前为止所取得的成就。
下面是我使用 JavaCV 从原始图像中截取的感兴趣区域。
Mat areaOfInterest = OpenCVUtils.getRegionOfInterest("image.jpg",295,200,23,25);
public static Mat getRegionOfInterest(String filePath , int x, int y, int width, int height){
Mat roi = null;
try{
Mat image = Imgcodecs.imread(filePath);
Rect region_of_interest= new Rect(x,y,width,height);
roi = image.submat(region_of_interest);
}catch (Exception ex){
}
return roi;
}
现在我试图找出感兴趣的区域中是否存在任何矩形。我也使用以下代码行来检测它。
Mat gray = new Mat();
Mat binary = new Mat();
Mat hierarchy = new Mat();
ArrayList<MatOfPoint> contours = new ArrayList<>();
cvtColor(image,gray,COLOR_BGR2GRAY);
Core.bitwise_not(gray,binary);
findContours(binary,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE);
if(contours.size() > 0){
for (MatOfPoint contour:contours) {
Rect rect = boundingRect(contour);
/// x = 0, y = 1 , w = 2, h =3
Point p1 = new Point(rect.x,rect.y);
Point p2 = new Point(rect.width + rect.x, rect.height+rect.y);
rectangle(image,p1,p2,new Scalar(0,0,255));
Imgcodecs.imwrite("F:\rect.png",image);
}
}
但是它没有找到图像内部的正方形,而是如下所示勾勒出图像的各个部分。
如果有人能将我推向正确的方向,那就太好了。
OpenCV 的 findContours()
将输入图像视为二值图像,其中所有为 0 的都是黑色,任何 >0 的像素都是白色。由于您正在读取 jpg
图像,压缩使得大多数白色像素不完全是白色,大多数黑色像素也不完全是黑色。因此,如果您有这样的输入图像:
3 4 252 250 3 1
3 3 247 250 3 2
3 2 250 250 2 2
4 4 252 250 3 1
3 3 247 250 3 2
3 2 250 250 2 2
然后 findContours()
将勾勒出整个事情的轮廓,因为它等同于所有 255(它们都 > 0)。
您需要做的就是用 threshold()
或 inRange()
之类的东西对图像进行二值化,这样您的图像实际上就会变成
0 0 255 255 0 0
0 0 255 255 0 0
0 0 255 255 0 0
0 0 255 255 0 0
0 0 255 255 0 0
0 0 255 255 0 0
那么你就可以正确地得到中心的 255 块的轮廓了。