问题一
sigmoid
函数,不知道使用一个什么样的 sigmoid
函数比较合适问题二:
问题:只考虑了 sigmoid
函数的变化趋势,而没有考虑到具体的值,函数值只在[-5,5]内有明显变化
解决:在像素变换公式上进行调整
原始公式为
int t = source_image.at(y, x)[c];
transformed_image.at(y, x)[c] = saturate_cast(t * ((contrast_value*0.1 / (1.00 + exp(-t))) + 1));
调整后公式为
double t = ((source_image.at(y, x)[c] - 127) / 255.00) * contrast_value * 0.1;//[-10, 10]
transformed_image.at(y, x)[c] = saturate_cast(source_image.at(y, x)[c] * ((1.00 / (1.00 + exp(-t))) + 0.3) + bright_value - 100);
-127
是为了让结果有正有负,这样像素小的会导致 1 + e − t 1+e^{-t} 1+e−t 更大,对比度调整之后,像素值更小。反之,像素值大的调整的程度不像像素值小的那样剧烈,因此会导致他们之间的像素差更大,因此对比度得到调整
/255
是为了限制 t t t 的范围,使其尽量在幂函数变化范围较明显的区域变动
contrast_value
就是滑动条需要改变的值,用于进行对比度调整
1 1 + e − t + 0.3 \frac{1}{1+e^{-t}} + 0.3 1+e−t1+0.3 ,加了一个系数是因为,如果不加系数的话,只调整对比度会导致变换后的像素值永远小于原像素值,这不是我们想要的。另一个原因是,这个可以平衡一下 t t t 的作用,不让 t t t 的影响程度这么大。(加的数值大小可以自行控制)
bright_value
比较好理解,就是单纯对像素值进行调整,用于亮度调整
问题三:利用调整公式,难以得到原图。个人认为是因为用了非线性变换,目前没有解决
调整效果比较明显,且都比较正常,实验结果达到预期效果
问题一
当图像中的像素值和背景图中对应位置像素值相差不大时,难以进行分辨,相减后前景图该位置基本为黑色,不符合预期要求。
以上述图片为例,当人身上的像素值小于背景像素值时,人的像素值减去背景像素值通过防止溢出处理后,结果图像对应位置像素值为0,不符合预期要求。
可以看到,基本将人物这一前景提取出来,但仍有噪声存在
背景相减实验可以多看一些降噪的算法,因为不太容易确定相减的标准
背景相减实验阈值选为90时得到的结果。轮廓清晰,达到预期效果
对于单通道图像"picture1",picture1.at(i,j)就表示在第i行第j列的像素值。
对于多通道图像如RGB图像"picture2",可以用picture2.at(i,j)[c]来表示某个通道中在(i,j)位置的像素值。
Vec3b可以看作是vector
由于在OpenCV中,使用imread读取到的Mat图像数据,都是用uchar类型的数据存储,对于RGB三通道的图像,每个点的数据都是一个Vec3b类型的数据。使用at定位方法如下:
img.at(row, col)[0] = 255; // 这是指修改B通道数据
img.at(row, col)[1] = 255; // 这是指修改G通道数据
img.at(row, col)[2] = 255; // 这是指修改R通道数据
srcImage.at(j, i) //表示的是 j 行 i 列 的这个像素
srcImage.at(Point(j, i)) //表示的是 坐标(j,i)的像素
Mat m = Mat::zeros(2, 2, CV_8UC3);//直接指明size和类型
transformed_image = Mat::zeros(source_image.size(), source_image.type());//创建一个和source_image一样类型的图
创建滑动条
CV_EXPORTS int createTrackbar(const String& trackbarname,
const String& winname,
int* value,
int count,
TrackbarCallback onChange = 0,
void* userdata = 0);
namedWindow("Transformed Window", WINDOW_AUTOSIZE);
createTrackbar("contrast", "Transformed Window", &contrast_value, 200, ContrastAndBright , 0);
createTrackbar("bright", "Transformed Window", &bright_value, 200, ContrastAndBright , 0);
static void ContrastAndBright(int pos , void* userdata) {
//value传值给pos , createTrackbar的第六个参数传递给userdata
for (int y = 0; y < source_image.rows; y++)
for (int x = 0; x < source_image.cols; x++)
for (int c = 0; c < 3; c++){
double t = ((source_image.at(y, x)[c] - 127) / 225.00) * contrast_value * 0.1;
transformed_image.at(y, x)[c] = saturate_cast(source_image.at(y, x)[c] * ((1.00 / (1.00 + exp(-t))) + 0.3) + bright_value - 100);
}
imshow("Display Window", source_image);
imshow("Transformed Window", transformed_image);
}
源码地址:Computer-Vision/实验一/源码 at main · SDU-NSY/Computer-Vision (github.com)