Rumah > Soal Jawab > teks badan
下面两版代码,第一个代码运行时灰度值不能随滚动条的调节而变化,但是第二版程序就可以。麻烦帮我分析一下为什么?环境是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;
}
阿神2017-04-17 13:33:51
我想告诉你,第一个程序并不是没有效果,而是第一个程序的状态已经保存到binaryImage中去了
经过第一次运行on_thresholdAdjustment函数后,binaryImage中的内容已经只有0、255两种值了
以后再次修改,也是基于binaryImage中仅有的0和255进行,因此阈值g_threshold就必然会失效,可以通过将阈值改成0你可以看到效果。
保持原始的信息是非常有必要的,不能总是基于计算出来的值进行计划,必须使用原始信息进行计算,如果你不想要3个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 srcImage;
int main()
{
//1.读取图像并在窗口中显示
srcImage = imread("dota.jpg", 1);
if (!srcImage.data)
{
cerr << "图片读取错误!\n";
return -1;
}
namedWindow("原图窗口");
imshow("原图窗口", srcImage);
waitKey(0);
// 把这里的代码删掉
namedWindow("二值化图像", 1);
createTrackbar("阈值 ", "二值化图像", &g_threshold, 150, on_thresholdAdjustment);
on_thresholdAdjustment(g_threshold, 0);
waitKey(0);
}
static void on_thresholdAdjustment(int, void*)
{
// 把代码粘贴到这里来,保证binaryImage每次都重新生成
//2.对灰度图像进行二值化处理
binaryImage = srcImage.clone();
if (!binaryImage.data)
{
cerr << "binaryImage is empty!\n" << endl;
}
cvtColor(srcImage, binaryImage, CV_RGB2GRAY);
// 把代码粘贴到这里来
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" << g_threshold << endl;
}