基本上我想为我的绘画应用程序实现颜色替换功能。 以下是原始和预期的输出
原文:
在改变用户选择的墙壁颜色以及一些替换阈值之后
我尝试了两种方法,但无法按预期工作
方法一:
Queue-based Flood Fill颜色替换算法
但是我以非常慢的速度获得低于输出并且没有保留墙壁阴影。
方法 2: 所以我试图查看另一个选项,并在下面找到来自 SO 的帖子 How to change a particular color in an image?
但我无法理解逻辑,也不确定我从第 3 步开始的代码实现。
请根据我的理解为每个步骤找到以下代码。
1) 使用 cvCvtColor 将图像从 RGB 转换为 HSV(我们只想 改变色调)。
IplImage *mainImage=[self CreateIplImageFromUIImage:[UIImage imageNamed:@"original.jpg"]];
IplImage *hsvImage = cvCreateImage(cvGetSize(mainImage), IPL_DEPTH_8U, 3);
IplImage *threshImage = cvCreateImage(cvGetSize(mainImage), IPL_DEPTH_8U, 3);
cvCvtColor(mainImage,hsvImage,CV_RGB2HSV);
2) 用指定 a 的 cvThreshold 隔离颜色 一定的公差(你想要一系列的颜色,而不是一种单一的颜色)。
cvThreshold(hsvImage, threshImage, 0, 100, CV_THRESH_BINARY);
3) 使用 Blob 检测丢弃低于最小尺寸的颜色区域 像 cvBlobsLib 这样的库。这将摆脱类似的点 场景中的颜色。 我需要指定原始图像还是阈值图像?
CBlobResult blobs = CBlobResult(threshImage, NULL, 0);
blobs.Filter( blobs, B_EXCLUDE, CBlobGetArea(), B_LESS, 10);
4) 用 cvInRangeS 屏蔽颜色并使用 生成的蒙版应用新的色调。
不确定此函数如何帮助颜色替换,也无法理解要提供的参数。
5) cvMerge 新图像与 由饱和度和亮度组成的图像的新色调 您在第一步中保存的 channel 。
我知道 cvMerge 将合并 H S 和 V 的三个 channel ,但我如何使用以上三个步骤的输出。
所以基本上坚持使用 opencv 实现,
如果可能,请指导我进行 opencv 实现或任何其他试用解决方案。
最佳答案
最后,我能够使用下面的 javacv 代码并同样移植到 opencv 来实现一些所需的输出。
这个解决方案有两个问题
- 没有边缘检测,我认为使用轮廓我可以实现它
替换的颜色具有平淡的色调和饱和度,应根据来源进行设置 像素色相差异但不确定如何实现。或许 使用 cvAddS 而不是 cvSet
IplImage image = cvLoadImage("sample.png"); CvSize cvSize = cvGetSize(image); IplImage hsvImage = cvCreateImage(cvSize, image.depth(),image.nChannels()); IplImage hChannel = cvCreateImage(cvSize, image.depth(), 1); IplImage sChannel = cvCreateImage(cvSize, image.depth(), 1); IplImage vChannel = cvCreateImage(cvSize, image.depth(), 1); cvSplit(hsvImage, hChannel, sChannel, vChannel, null); IplImage cvInRange = cvCreateImage(cvSize, image.depth(), 1); CvScalar source=new CvScalar(72/2,0.07*255,66,0); //source color to replace CvScalar from=getScaler(source,false); CvScalar to=getScaler(source, true); cvInRangeS(hsvImage, from , to, cvInRange); IplImage dest = cvCreateImage(cvSize, image.depth(), image.nChannels()); IplImage temp = cvCreateImage(cvSize, IPL_DEPTH_8U, 2); cvMerge(hChannel, sChannel, null, null, temp); cvSet(temp, new CvScalar(45,255,0,0), cvInRange);// destination hue and sat cvSplit(temp, hChannel, sChannel, null, null); cvMerge(hChannel, sChannel, vChannel, null, dest); cvCvtColor(dest, dest, CV_HSV2BGR); cvSaveImage("output.png", dest);
阈值计算方法
CvScalar getScaler(CvScalar seed,boolean plus){
if(plus){
return CV_RGB(seed.red()+(seed.red()*thresold),seed.green()+(seed.green()*thresold),seed.blue()+(seed.blue()*thresold));
}else{
return CV_RGB(seed.red()-(seed.red()*thresold),seed.green()-(seed.green()*thresold),seed.blue()-(seed.blue()*thresold));
}
}
关于iphone - iphone 应用程序图像中的颜色替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15082025/