图像外轮廓提取

遥感服务 2014-06-05 12:11:37

如图所示,白色灰度都是1,黑色都是0,如何去除白色里面的黑色,即把白色里面的黑色变成白色。
...全文
778 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
昨夜无风 2014-06-09
  • 打赏
  • 举报
回复
无非就是连通统计,把黑的作为目标,统计黑色的连通数,然后保留最大的,填充其他的即可!
schlafenhamster 2014-06-09
  • 打赏
  • 举报
回复
既然 CV 可以 找到 联通域, 何不 再找 那个 小的 黑的 联通域。 填起来 也 小 很多。
遥感服务 2014-06-09
  • 打赏
  • 举报
回复
引用 8 楼 wangyaninglm 的回复:
opencv2计算机视觉编程手册中第七章,有个提取联通区域轮廓,你这个能不能提取出来,轮廓内部的全部变成白色就行了 cv::findContours
/*------------------------------------------------------------------------------------------*\
   This file contains material supporting chapter 7 of the cookbook:  
   Computer Vision Programming using the OpenCV Library. 
   by Robert Laganiere, Packt Publishing, 2011.

   This program is free software; permission is hereby granted to use, copy, modify, 
   and distribute this source code, or portions thereof, for any purpose, without fee, 
   subject to the restriction that the copyright notice may not be removed 
   or altered from any source or altered source distribution. 
   The software is released on an as-is basis and without any warranties of any kind. 
   In particular, the software is not guaranteed to be fault-tolerant or free from failure. 
   The author disclaims all warranties with regard to this software, any use, 
   and any consequent failure, is purely the responsibility of the user.
 
   Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
\*------------------------------------------------------------------------------------------*/
#include "StdAfx.h"
#include <iostream>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

int main()
{
	// Read input binary image
	cv::Mat image= cv::imread("test.png",0);
	if (!image.data)
		return 0; 

	cv::namedWindow("Binary Image");
	cv::imshow("Binary Image",image);

	// Get the contours of the connected components
	std::vector<std::vector<cv::Point>> contours;
	cv::findContours(image, 
		contours, // a vector of contours 
		CV_RETR_EXTERNAL, // retrieve the external contours
		CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours

	// Print contours' length
	std::cout << "Contours: " << contours.size() << std::endl;
	std::vector<std::vector<cv::Point>>::const_iterator itContours= contours.begin();
	for ( ; itContours!=contours.end(); ++itContours) 
	{

		std::cout << "Size: " << itContours->size() << std::endl;
	}

	// draw black contours on white image
	cv::Mat result(image.size(),CV_8U,cv::Scalar(255));
	cv::drawContours(result,contours,
		-1, // draw all contours
		cv::Scalar(0), // in black
		2); // with a thickness of 2

	cv::namedWindow("Contours");
	cv::imshow("Contours",result);


	// draw contours on the original image
	cv::Mat original= cv::imread("test.png");
	cv::drawContours(original,contours,
		-1, // draw all contours
		cv::Scalar(255,255,255), // in white
		-1); // with a thickness of 2

	cv::namedWindow("Contours on Animals");
	cv::imshow("Contours on Animals",original);

	// Let's now draw black contours on white image
	result.setTo(cv::Scalar(255));
	cv::drawContours(result,contours,
		-1, // draw all contours
		cv::Scalar(0), // in black
		-1); // with a thickness of 1
	image= cv::imread("test.png",0);



	cv::waitKey();
	return 0;
}
程序效果很不错,谢谢。
poy49295 2014-06-09
  • 打赏
  • 举报
回复
OpenCV里找轮廓都在一个API里面,与其找内边,直接找到最外边,然后填充更方便
大飞哥666 2014-06-06
  • 打赏
  • 举报
回复
你可以选择一个矩形模板,如100*100像素(具体大小可根据中间多边形的大小确定),然后以此模板在图像中进行匹配,如果存在一个区域——它的四周都为白色,并且中间存在黑色像素点,然后将此矩形模板内的像素全部填充为白色即可。
schlafenhamster 2014-06-06
  • 打赏
  • 举报
回复
这个 图 不是 凸包 应该 用 填充算法, 问题 在 如何 发现 内部的 黑点 位置,
遥感服务 2014-06-06
  • 打赏
  • 举报
回复
引用 5 楼 lx624909677 的回复:
可以用OpenCV的话就暴力点。。遍历像素点。。。直接修改。。比如:
if(dst.channels() == 1)//dst是Mat类型的对象,里面放着就是图像
	{
		for(int i=0; i<dst.rows; i++)
		{
			sum[i] = 0;
			for(int j=0; j<dst.cols; j++)
			{
				if(dst.at<uchar>(i,j)){.....}//这里就是遍历每个像素点的数值了。修改同样直接赋值就可以!


			}
		}
	}
你这样循环的话,所有的黑色都变成了白色吧,我只是希望白色内部的黑色变成白色,白色外部的黑色不变。
lx624909677 2014-06-06
  • 打赏
  • 举报
回复
可以用OpenCV的话就暴力点。。遍历像素点。。。直接修改。。比如:
if(dst.channels() == 1)//dst是Mat类型的对象,里面放着就是图像
	{
		for(int i=0; i<dst.rows; i++)
		{
			sum[i] = 0;
			for(int j=0; j<dst.cols; j++)
			{
				if(dst.at<uchar>(i,j)){.....}//这里就是遍历每个像素点的数值了。修改同样直接赋值就可以!


			}
		}
	}
shiter 2014-06-06
  • 打赏
  • 举报
回复
opencv2计算机视觉编程手册中第七章,有个提取联通区域轮廓,你这个能不能提取出来,轮廓内部的全部变成白色就行了

cv::findContours
/*------------------------------------------------------------------------------------------*\
This file contains material supporting chapter 7 of the cookbook:
Computer Vision Programming using the OpenCV Library.
by Robert Laganiere, Packt Publishing, 2011.

This program is free software; permission is hereby granted to use, copy, modify,
and distribute this source code, or portions thereof, for any purpose, without fee,
subject to the restriction that the copyright notice may not be removed
or altered from any source or altered source distribution.
The software is released on an as-is basis and without any warranties of any kind.
In particular, the software is not guaranteed to be fault-tolerant or free from failure.
The author disclaims all warranties with regard to this software, any use,
and any consequent failure, is purely the responsibility of the user.

Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
\*------------------------------------------------------------------------------------------*/
#include "StdAfx.h"
#include <iostream>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

int main()
{
// Read input binary image
cv::Mat image= cv::imread("test.png",0);
if (!image.data)
return 0;

cv::namedWindow("Binary Image");
cv::imshow("Binary Image",image);

// Get the contours of the connected components
std::vector<std::vector<cv::Point>> contours;
cv::findContours(image,
contours, // a vector of contours
CV_RETR_EXTERNAL, // retrieve the external contours
CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours

// Print contours' length
std::cout << "Contours: " << contours.size() << std::endl;
std::vector<std::vector<cv::Point>>::const_iterator itContours= contours.begin();
for ( ; itContours!=contours.end(); ++itContours)
{

std::cout << "Size: " << itContours->size() << std::endl;
}

// draw black contours on white image
cv::Mat result(image.size(),CV_8U,cv::Scalar(255));
cv::drawContours(result,contours,
-1, // draw all contours
cv::Scalar(0), // in black
2); // with a thickness of 2

cv::namedWindow("Contours");
cv::imshow("Contours",result);


// draw contours on the original image
cv::Mat original= cv::imread("test.png");
cv::drawContours(original,contours,
-1, // draw all contours
cv::Scalar(255,255,255), // in white
-1); // with a thickness of 2

cv::namedWindow("Contours on Animals");
cv::imshow("Contours on Animals",original);

// Let's now draw black contours on white image
result.setTo(cv::Scalar(255));
cv::drawContours(result,contours,
-1, // draw all contours
cv::Scalar(0), // in black
-1); // with a thickness of 1
image= cv::imread("test.png",0);



cv::waitKey();
return 0;
}


Guilty 2014-06-05
  • 打赏
  • 举报
回复
基本是个填充算法,面积小的填了,面积大恢复
shiter 2014-06-05
  • 打赏
  • 举报
回复
我知道二楼同学搞出来肯定效果不好
Guilty 2014-06-05
  • 打赏
  • 举报
回复
引用 2 楼 hhhh63 的回复:
凸多边形可以用扫描法,取任一条横线或竖线,如果两边有白的,中间是黑的就变白
“或”肯定不行,会把外圈的黑角削掉。“与”大概行吧。
hhhh63 2014-06-05
  • 打赏
  • 举报
回复
凸多边形可以用扫描法,取任一条横线或竖线,如果两边有白的,中间是黑的就变白

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧