|
发表于 2019-3-19 16:55:07
|
显示全部楼层
本帖最后由 xx_player 于 2019-3-20 09:39 编辑
opencv是第三方软件,虽然问题只一个,调试要搞半歇。
错在这:g_dstImage.at<Vec3d>(i, j)[c] = saturate_cast<uchar>((g_DuiBiDu*0.01) * g_srcImage.at<Vec3d>(i, j)[c] + g_LiangDu);
Vec3d是3个双精度值,而实际容量是3个字节值,地址溢出。改成Vec3b即可。
完整参照代码如下
//
//编译环境:window10
//1.opencv官网下载4.0 https://opencv.org/opencv-4-0-0.html
//2.点击执行,自动解包到文件夹.文件夹可以自命名为d:\opencv
//3.此电脑右键属性->高级系统属性->高级->环境变量->系统变量选中Path后选编辑->新建环境变量d:\opencv\build\x64\vc14
//4.新建x64调试版控制台程序,只支持x64,不支持x86。项目属性VC++目录选包含目录,添加
// d:\opencv\opencv\build\include
// d:\opencv\opencv\build\include\opencv2
//5.项目属性VC++目录选库目录,添加
// d:\opencv\opencv\build\x64\vc14\lib
//6.项目属性链接器选输入,选附加依赖项,添加
// opencv_world400d.lib
//7.粘贴代码
//如果代码不红,说明设置正确,编译运行.
//8.别忘了,把动态库d:\opencv\opencv\build\x64\vc14\bin\opencv_world400d.dll拷贝到debug目录
// 避免运行时,找不到该运行库。
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <Windows.h>
#include <iostream>
using namespace cv;
using namespace std;
namespace nsdemo {
int g_LiangDu = 0, g_DuiBiDu = 0;
Mat g_srcImage, g_dstImage;
static void on_change(int, void*);
}
using namespace nsdemo;
int main()
{
String filename = "d:\\1.jpg";
g_srcImage = imread(filename);
if (g_srcImage.empty())
{
wcout << "读取"<<filename.c_str() << "文件失败!错误码=" << GetLastError() << endl;
}
g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type());
wcout << "宽=" << g_srcImage.size().width << "高=" << g_srcImage.size().height << endl;
wcout << "拖动跟踪栏按钮才有效果,任何子窗上按ESC键退出" << endl;
g_LiangDu = 80;
g_DuiBiDu = 80;
// 建立两主窗口
namedWindow("效果图窗口");
namedWindow("原始图窗口");
// 效果图窗口建立2子窗
createTrackbar("亮度", "效果图窗口", &g_LiangDu, 200, on_change);
createTrackbar("对比度", "效果图窗口", &g_DuiBiDu, 255, on_change);
// 显示子窗
imshow("原始图窗口", g_srcImage);
imshow("效果图窗口", g_dstImage);
//按ESC键退出,33ms检测按键
while (waitKey(33) != 27){}
destroyAllWindows();
return 0;
}
void nsdemo::on_change(int, void*)
{
for (int i = 0; i < g_srcImage.rows;i++)
{
for (int j = 0; j < g_srcImage.cols; j++)
{
for (int c = 0; c < 3; c++)
{
//g_dstImage.at<Vec3d>(i, j)[c] = saturate_cast<uchar>((g_DuiBiDu*0.01) * g_srcImage.at<Vec3d>(i, j)[c] + g_LiangDu);
g_dstImage.at<Vec3b>(i, j)[c] = saturate_cast<uchar>((g_DuiBiDu*0.01) * g_srcImage.at<Vec3b>(i, j)[c] + g_LiangDu);
}
}
}
imshow("原始图窗口", g_srcImage);
imshow("效果图窗口", g_dstImage);
cout << "亮度=" << g_LiangDu << " 对比度=" << g_DuiBiDu << endl;
}
其中:出错的那行,理解代码是这样地
int pos = i * g_srcImage.cols * 3 + j * 3;
float r = g_srcImage.data[pos + 0];
float g = g_srcImage.data[pos + 1];
float b = g_srcImage.data[pos + 2];
//计算公式
r =(float) r *g_DuiBiDu*0.01f + g_LiangDu;
g =(float) g *g_DuiBiDu*0.01f + g_LiangDu;
b =(float) b *g_DuiBiDu*0.01f + g_LiangDu;
g_dstImage.data[pos + 0] = r>255 ? 255 : (BYTE)r;
g_dstImage.data[pos + 1] = g>255 ? 255 : (BYTE)g;
g_dstImage.data[pos + 2] = b>255 ? 255 : (BYTE)b;
可以替换测试。另外
imread(filename)实际等于 imread(filename,1),载入的是BGR三通道颜色,没有A.用的硬编码乘3

|
|