下面两版代码,第一个代码运行时灰度值不能随滚动条的调节而变化,但是第二版程序就可以。麻烦帮我分析一下为什么?环境是vs2012+opencv2.4.8
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
static void on_thresholdAdjustment(int, void*); //滚动条回调函数
int g_threshold=70;
Mat binaryImage;
Mat dstImage;
int main()
{
//1.读取图像并在窗口中显示
Mat srcImage = imread("dota.jpg", 1);
if (!srcImage.data)
{
cerr <<"图片读取错误!\n";
return -1;
}
namedWindow("原图窗口");
imshow("原图窗口", srcImage);
waitKey(0);
//2.对灰度图像进行二值化处理
//srcImage.copyTo(binaryImage);
binaryImage = srcImage.clone();
if (!binaryImage.data)
{
cerr << "binaryImage is empty!\n" <<endl;
}
cvtColor(srcImage, binaryImage, CV_RGB2GRAY);//COLOR_RGB2GRAY CV_RGBA2GRAY
namedWindow("二值化图像", 1);
createTrackbar("阈值 ", "二值化图像", &g_threshold, 150, on_thresholdAdjustment);
on_thresholdAdjustment(g_threshold, 0);
waitKey(0);
}
static void on_thresholdAdjustment(int, void*)
{
int rowNumber = binaryImage.rows;
int colNumber = binaryImage.cols;
for (int i = 0; i < rowNumber; i++)
{
uchar* data = binaryImage.ptr<uchar>(i); //获取第i行的首地址
for(int j = 0; j < colNumber; j++)
{
if (data[j] < (g_threshold))
{
data[j] = 0;
}
else
{
data[j] = 255;
}
}
}
imshow("二值化图像", binaryImage);
cout<< "finished" << endl;
}
第二版程序 使用了一个中间的mat
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
static void on_thresholdAdjustment(int, void*); //滚动条回调函数
int g_threshold=70;
Mat binaryImage;
Mat dstImage;
int main()
{
//1.读取图像并在窗口中显示
Mat srcImage = imread("dota.jpg", 1);
if (!srcImage.data)
{
cerr <<"图片读取错误!\n";
return -1;
}
namedWindow("原图窗口");
imshow("原图窗口", srcImage);
waitKey(0);
//2.对灰度图像进行二值化处理
//srcImage.copyTo(binaryImage);
binaryImage = srcImage.clone();
if (!binaryImage.data)
{
cerr << "binaryImage is empty!\n" <<endl;
}
cvtColor(srcImage, binaryImage, CV_RGB2GRAY);//COLOR_RGB2GRAY CV_RGBA2GRAY
dstImage = Mat::zeros(binaryImage.size(), binaryImage.type());//这里不同
namedWindow("二值化图像", 1);
createTrackbar("阈值 ", "二值化图像", &g_threshold, 150, on_thresholdAdjustment);
on_thresholdAdjustment(g_threshold, 0);
waitKey(0);
}
static void on_thresholdAdjustment(int, void*)
{
int rowNumber = binaryImage.rows;
int colNumber = binaryImage.cols;
for (int i = 0; i < rowNumber; i++)
{
uchar* data = binaryImage.ptr<uchar>(i); //获取第i行的首地址
uchar* data2 = dstImage.ptr<uchar>(i); //这里不同
for(int j = 0; j < colNumber; j++)
{
if (data[j] < (g_threshold))
{
data2[j] = 0;
}
else
{
data2[j] = 255;
}
}
}
imshow("二值化图像", dstImage);
cout<< "finished" << endl;
}
我想告訴你,第一個程式並不是沒有效果,而是第一個程式的狀態已經保存到binaryImage中去了
經過第一次運行on_thresholdAdjustment函數後,binaryImage中的內容已經只有0、255兩種值了
以後再次修改,也是基於binaryImage中僅有的0和255進行,因此閾值g_threshold就必然會失效,可以透過將閾值改成0你可以看到效果。
保持原始的資訊是非常有必要的,不能總是基於計算出來的值進行計劃,必須使用原始資訊進行計算,如果你不想要3個Mat的話,可以這樣改: