再识opencv

一、图像灰度变换(点运算)

线性点运算

利用线性方程s=ar+b来完成对图像的点运算,s为输出灰度值,r 为输入灰度值,a 和b 为变换系数。
通过调整a和b的取值,可以得到不同的变换效果:

  • 当a=1,b=0时,输入和输出相等,即输出原图像。
  • 当a=1,b>0时,输出灰度值变大,图像整体变亮。
  • 当a=1,b<0时,输出灰度值变小,图像整体变暗。
  • 当a>1时,输出图像对比度增大。
  • 当0<a<1时,输出图像对比度减小。
  • 当a<0时,图像暗区变亮,亮区变暗,完成图像求补
    我们来看一下例子:
import matplotlib.pyplot as plt
import cv2
import numpy as np
img=cv2.imread('1.bmp',0)
a,b=1,0
img1=cv2.add(cv2.multiply(1,img),b)
plt.subplot(231),plt.imshow(img1,'gray')
plt.title('a=1,b=0')
a=1
b=50
img2=cv2.add(cv2.multiply(a,img),b)
plt.subplot(232),plt.imshow(img2,"gray")
plt.title('a=1,b=50')
a,b=1,-50
img3=cv2.add(cv2.multiply(a,img),b)
plt.subplot(233),plt.imshow(img3,'gray')
plt.title('a=1,b=50')
a,b=1.5,0
img4=cv2.add(cv2.multiply(a,img),b)
plt.subplot(234),plt.imshow(img4,'gray')
plt.title('a=1.5,b=0')
a,b=0.3,0
img5=cv2.add(cv2.multiply(a,img),b)
plt.subplot(235),plt.imshow(img5,'gray')
plt.title('a=0.3,b=0')
a,b=-1,0
img6=cv2.add(cv2.multiply(a,img),b)
plt.subplot(236),plt.imshow(img6,'gray')
plt.title('a=-1,b=0')
plt.show()

该代码对以上六种情况都做了实际操作,关键在于如何在原图像上进行线性运算得到新的图像,课本中用了cv2库中的add函数,但这样有一个问题:图像数据通常是以 uint8 格式存储的,其取值范围是 0 到 255,当 a 和 b 的值使得图像中的某些像素值超出这个范围时,就会引发溢出错误。于是在这里我用cv2.convertScaleAbs函数,该函数可以对图像进行缩放和平移操作,并且会自动处理溢出问题。(注:也可以使用归一化处理img=img/255)
在这里插入图片描述

另外在plt.imshow函数中需要表明输出图像为灰度,否则即使将img强制转化为了灰度图仍会输出彩色图,类似于这样:
在这里插入图片描述

非线性点运算

非线性点运算有两种,分别是对数运算幂次运算。其中幂次变换比对数变换更加复杂。于是我们便用幂次变化对图像进行处理。
指数方程为s=cr**γ ,s为输出灰度值,r 为输入灰度值,c 和γ 为正常数,γ 值以1为分界线,当值大于1时,可以产生和对数运算相同的结果,即将灰度值低的区域进行扩展,灰度值高的区域进行压缩,提高图像亮度;当γ 值小于1时,将得到相反的结果,即灰度值高的区域进行扩展,将灰度值低的区域进行压缩,减小图像亮度;当c=γ=1是,将是简单的线性变换,输入与输出相等。

import cv2
import matplotlib.pyplot as plt
img=cv2.imread('1.bmp',0)
img=img/255
plt.subplot(231)
plt.imshow(img,'gray')
plt.title('original')
r=0.1
plt.subplot(232)
temp=cv2.pow(img,0.1)
plt.imshow(temp,cmap='gray')
plt.title('c=1,r=0.1')
r=0.4
plt.subplot(233)
temp=cv2.pow(img,0.4)
plt.imshow(temp,cmap='gray')
plt.title('c=1,r=0.4')
r=1
plt.subplot(234)
temp=cv2.pow(img,1)
plt.imshow(temp,cmap='gray')
plt.title('c=1,r=1')
r=2.5
plt.subplot(235)
temp=cv2.pow(img,2.5)
plt.imshow(temp,cmap='gray')
plt.title('c=1,r=2.5')
r=10
plt.subplot(236)
temp=cv2.pow(img,10)
plt.imshow(temp,cmap
### 使用OpenCV和C++实现交通信号灯中绿灯的检测与别 #### 1. 图像预处理 为了提高后续处理的效果,在进行颜色过滤之前通常先对图像进行一些基本的预处理操作。这一步骤可以减少噪声并增强目标特征。 ```cpp cv::Mat preprocessImage(const cv::Mat& input) { cv::Mat gray, blurred; // 将输入图片转换成灰度图 cvtColor(input, gray, CV_BGR2GRAY); // 高斯模糊去噪 GaussianBlur(gray, blurred, Size(7, 7), 0); return blurred; } ``` #### 2. 绿色区域分割 通过HSV色彩空间来定义绿色范围,从而提取可能存在的绿灯部分。由于不同环境下的光照条件变化较大,因此需要适当调整阈值以适应实际场景需求[^1]。 ```cpp std::vector<cv::Vec3f> detectGreenLights(cv::Mat hsvFrame) { std::vector<cv::Vec3f> circles; // 定义绿色的颜色区间 (Hue:色调; Saturation:饱和度; Value:亮度) cv::Scalar lower_green = cv::Scalar(40, 80, 80); cv::Scalar upper_green = cv::Scalar(90, 255, 255); // 创建掩码用于筛选特定颜色 cv::Mat mask; inRange(hsvFrame, lower_green, upper_green, mask); // 形态学操作去除小斑点干扰 erode(mask, mask, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); dilate(mask, mask, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); return findContoursAndDetectCircles(mask); } ``` #### 3. 圆形轮廓查找 利用霍夫变换圆检测算法寻找圆形物体作为潜在的红绿灯候选对象,并进一步验证其形状特性是否符合预期标准。 ```cpp std::vector<cv::Vec3f> findContoursAndDetectCircles(const cv::Mat& binaryImg){ std::vector<std::vector<cv::Point>> contours; std::vector<Vec4i> hierarchy; // 查找轮廓 findContours(binaryImg.clone(), contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE); vector<vector<Point>> approx_contours(contours.size()); for(size_t i=0;i<contours.size();i++){ approxPolyDP(Mat(contours[i]),approx_contours[i],arcLength(Mat(contours[i]),true)*0.02,true); if(approx_contours[i].size() >= 8 && contourArea(contours[i]) > 100){ // 这里假设近似多边形顶点数大于等于8即认为是圆 Point2f center; float radius; minEnclosingCircle((Mat)approx_contours[i],center,radius); Vec3f circleInfo(center.x,center.y,radius); circles.push_back(circleInfo); } } return circles; } ``` #### 4. 结果展示 最后将找到的目标绘制到原始帧上以便观察效果。 ```cpp void drawDetectedObjects(cv::Mat &frame, const std::vector<cv::Vec3f>& detected_objects){ for(auto obj : detected_objects){ Scalar color = Scalar(0,255,0); // Green Color // 绘制边界框或其它标记方式突出显示被发现的对象 rectangle(frame,cv::Rect(Point(obj[0]-obj[2],obj[1]-obj[2]), Point(obj[0]+obj[2],obj[1]+obj[2])), color,2); } } ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值