基于C++的OpenCV亮度调整工具:内置卡尺拖拽测量功能,附全套源码及详细注释
完整代码加了个亮度直方图的彩蛋——在窗口右下角用颜色条显示当前区域亮度分布,用cv::calcHist实现。直接上代码先看效果:按住鼠标左键拖动生成卡尺,松开自动计算区域亮度。支持多组测量,按'c'清屏,按'q'退出。注意这里offset计算用了sin/cos组合,实测比单用cos稳定,尤其处理对角线方向时不会抽搐。processROI那步后面说。基于c++的opencv亮度工具,可利用卡尺进行拖
基于c++的opencv亮度工具,可利用卡尺进行拖拽测量,仅提供全套源码加注释
直接上代码先看效果:按住鼠标左键拖动生成卡尺,松开自动计算区域亮度。支持多组测量,按'c'清屏,按'q'退出。核心代码分三块——卡尺绘制、事件处理、亮度计算,咱们拆开说。
先看卡尺绘制这骚操作:
// 画带刻度的卡尺线
void drawRuler(Mat& frame, Point start, Point end) {
line(frame, start, end, Scalar(0, 255, 0), 2); // 主轴线绿
// 刻度生成算法
double angle = atan2(end.y - start.y, end.x - start.x);
for(int i=0; i<=10; i++){
Point tick = start + (end - start) * i / 10;
Point offset(10 * sin(angle), 10 * cos(angle)); // 垂直方向偏移
line(frame, tick - offset, tick + offset, Scalar(0, 200, 0), 1);
}
}
这个刻度生成用三角函数算垂直方向,比固定方向旋转更丝滑。注意这里offset计算用了sin/cos组合,实测比单用cos稳定,尤其处理对角线方向时不会抽搐。
鼠标事件处理是灵魂:
// 全局记录坐标和拖动状态
struct {
Point start, current;
bool dragging = false;
} rulerState;
// 鼠标回调
void onMouse(int event, int x, int y, int flags, void* userdata) {
switch(event){
case EVENT_LBUTTONDOWN:
rulerState.start = Point(x, y);
rulerState.dragging = true;
break;
case EVENT_MOUSEMOVE:
if(rulerState.dragging){
rulerState.current = Point(x, y);
Mat temp = workingFrame.clone();
drawRuler(temp, rulerState.start, rulerState.current);
imshow("Brightness Tool", temp);
}
break;
case EVENT_LBUTTONUP:
rulerState.dragging = false;
processROI(rulerState.start, Point(x, y)); // 触发亮度计算
break;
}
}
这里有个坑:直接在原图上绘制会导致残留线段。所以每次都要clone工作副本,这样松开鼠标时原图不受影响。processROI那步后面说。
基于c++的opencv亮度工具,可利用卡尺进行拖拽测量,仅提供全套源码加注释
亮度计算用了个取巧的方法:
void processROI(Point pt1, Point pt2) {
Rect roi = Rect(pt1, pt2); // 自动处理坐标正反
if(roi.area() < 10) return; // 防误触
Mat region = srcImage(roi);
Scalar mean = cv::mean(region); // 三通道均值
// 结果可视化
rectangle(workingFrame, roi, Scalar(150, 75, 255), 2);
string text = format("Lum:%.1f", mean[0]);
putText(workingFrame, text, roi.br() + Point(5,15),
FONT_HERSHEY_SIMPLEX, 0.5, Scalar(200,100,255), 1);
}
这里mean取的是灰度值,如果原图是彩色的建议转成YUV空间取Y分量更准。不过实测RGB均值在多数情况够用,看需求改。
完整代码加了个亮度直方图的彩蛋——在窗口右下角用颜色条显示当前区域亮度分布,用cv::calcHist实现。编译注意链opencv_imgproc模块,有些发行版默认没带。
源码已扔Github(地址见文末),包含CMakeLists文件和测试图片。重点函数都写了中文注释,改参数建议优先调这几个:
- drawRuler里的刻度密度(10等分)
- processROI的亮度显示精度(.1f)
- 颜色阈值判断逻辑(默认没做)
这工具实测在工业检测场景挺实用,比如PCB板亮度均匀性检测。顺手改改还能做实时色差分析,有空再唠。

更多推荐
所有评论(0)