OpenCV图像操纵
OpenCV Image Manipulation
我正试图找出两张图像中的差异。
场景:假设我有两张图像,一张是背景,另一张是在背景前面的人,我想把这两张图像相减,这样我就可以得到人的位置,也就是说,程序可以检测出人站在哪里,并将相减后的图像作为输出。
我设法想出的代码是从相机中拍摄两张图像并重新调整它们的大小,并将这两张图像转换为灰度。我想知道这之后该怎么办。我检查了OpenCV提供的减法函数,但它以数组作为输入,所以我不知道如何进行。
我写的代码是:
cap>>frame; //gets the first image
cv::cvtColor(frame,frame,CV_RGB2GRAY); //converts it to gray scale
cv::resize(frame,frame,Size(30,30)); //re-sizes it
cap>>frame2;//gets the second image
cv::cvtColor(frame2,frame2,CV_RGB2GRAY); //converts it to gray scale
cv::resize(frame2,frame2,Size(30,30)); //re-sizes it
现在我可以简单地使用减法函数了吗?比如:
cv::subtract(frame_gray,frame,frame);
还是先应用一些滤波器,然后使用减法函数?
正如其他人所注意到的,这是一个棘手的问题:很容易想出一个有时会奏效的破解方法,很难想出一个在大多数情况下只需最少人工干预就能奏效的解决方案。此外,如果可以严格控制背景的材质和照明,则操作会容易得多。专业应用程序被称为"镀铬"(特别是在电视行业)、"蓝屏"、"遮片"或"旅行遮片"(在电影摄影中)、计算机视觉中的"背景去除"。
Petro Vlahos多年前就完成了对准均匀背景进行抠图的开创性工作。其基本算法的专利已经过期,所以你可以带着它们进城(并找到各种质量的开源实现)。不用说,IANAL,所以请做好专利主题的功课。
消除更复杂的背景仍然是一个活跃的研究领域,尤其是在没有3D信息的情况下。你可能想看看MS research最近发表的几篇研究论文(a.Criminisi在这方面做了一些工作)。
使用减法是不合适的,因为它可能会导致某些值变为负值,并且只有当您试图查看是否存在差异(布尔值true/false)时才有效。
如果你需要得到不同的像素,你应该逐个像素进行比较,比如:
int rows = frame.rows;
int cols = frame.cols;
cv::Mat diffImage = cv::Mat::zeros(rows, cols, CV_8UC1);
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < cols; ++j)
{
if(frame.at<uchar>(i,j) != frame2.at<uchar>(i,j))
diffImage.at<uchar>(i, j) = 255;
}
}
现在,您可以显示或保存diffImage。所有不同的像素都将是白色的,而相似的像素将是黑色的
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 平均图像时图像损坏
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- C++setiosflags函数操纵器-未确定的缩进
- 将RGB图像保存为PPM格式
- 将图像添加到资源文件夹UWP C++
- 彩色图像的卤化物处理平均值
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 重新定位图像时如何前进到下一个内存块
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- 为什么 BMP 图像上的 imwrite 会卡住/不返回?
- Gstreamer:每 5 秒使用多文件墨水保存图像/jpeg
- Dosbox图像操纵库下的Turbo-C
- OpenCV图像操纵