c++解决实际问题

来源:互联网 发布:php apache 安装配置 编辑:程序博客网 时间:2024/05/05 00:09

最近做智能小车的时候我突然想起一个问题,就是当前面有弯路,应该怎么如何控制转弯,最近一直查相关文档,收获甚微,感觉这个东西想做好真的很难。做着做着我发现这是一个图像问题,于是扔下了手中东西来看看图像,学习一下opencv  。

好吧,这要从哪里说起呢?

起点是看到一个拉普拉斯算法的实现,于是自己也模仿着写了一下,代码如下:

for (int i = 1; i < img.rows - 1; i++)
{
const uchar *previous = img.ptr<const uchar >(i - 1);
const uchar *current = img.ptr<const uchar>(i);
const uchar *next = img.ptr<const uchar>(i + 1);
uchar *output = img2.ptr<uchar>(i);
for (int j = 1; j < img.cols*3 - 1; j++)
{
*(++output) = saturate_cast<uchar>(5 * current[j] - current[j - 1] - current[j + 1] - next[j] - previous[j]);
}
}


拉普拉斯意义就是用上下两个个二次偏导数的和,

g(x,y)= f(x,y)+4f(x,y) - f(x--1,y)-f(x+1,y)-f(x,y-1)-f(x,y+1)

程序里面的sstureate是防止所加的和超过255所加的一个限制。ptr的参数是行数,ptr(j)是第i行的指针,然后每加3次就会走到下一个像素。故在里面的for循环中img.cols *3 。这里买你有个函数功能是二值化,threshold,他后面在二值化的算法是otsu,otsu就是先统计0~255像素中每个像素的个数。将x下面的像素所占比例和上面所占比例求出来为p1,p2。x上面的平均灰度和x下面的平均灰度为w1,w2。总体的平均灰度是w,根据最小二乘

w = w1*p1 + w2*p2 ;

求取方差:p1*(w1-w)^2 + p2*(w2-2)^2 

将一式带入根据最小二乘的思想求取极小值此时就是最佳的阈值x。


在求取直线过程中用到的houghLines函数,这个函数返回<vec2f>,两个float型的变量,第一个是rou ,第二个是theta对应极坐标系下面的,我们后期还要对其进行变换成直角坐标系下的图,再用line去画出来。至于滤波器我采用的是blur均值滤波器,当然你也可以采用其他的。注意其实boxblur就是一个特殊的blur滤波器。

整体代码如下:


#include <iostream>
#include <opencv2\opencv_modules.hpp>
#include <opencv2\opencv.hpp>
#include <vector>


using namespace std;
using namespace cv;


int main()
{
Mat img = imread("C:\\Users\\徐鹏\\Desktop\\1.jpg");
Mat img2;
cout << img.cols << endl;
img2.create(img.size(), img.type());
cout << img2.cols << endl;
for (int i = 1; i < img.rows - 1; i++)
{
const uchar *previous = img.ptr<const uchar >(i - 1);
const uchar *current = img.ptr<const uchar>(i);
const uchar *next = img.ptr<const uchar>(i + 1);
uchar *output = img2.ptr<uchar>(i);
for (int j = 1; j < img.cols*3 - 1; j++)
{
*(++output) = saturate_cast<uchar>(5 * current[j] - current[j - 1] - current[j + 1] - next[j] - previous[j]);
}
}
img2.row(0).setTo(Scalar(0));
img2.row(img2.rows - 1).setTo(Scalar(0));
img2.col(0).setTo(Scalar(0));
img2.col(img2.cols - 1).setTo(Scalar(0));
blur(img2, img2, Size(7, 7));
cvtColor(img2,img2 ,CV_RGB2GRAY);
Canny(img2, img2, 200, 150, 3);  //输入一定是灰度图
threshold(img2, img2, 0, 255, CV_THRESH_OTSU);
vector<Vec2f>lines;
HoughLines(img2,lines,1, CV_PI/180,240,0,0);
cout << lines.size();
vector<Vec2f>::const_iterator it = lines.begin();
while (it != lines.end())
{
float rho = (*it)[0];
float theta = (*it)[1];
if (theta < CV_PI / 4 || theta>3*CV_PI/4)
{
Point pt1(rho / cos(theta), 0);
Point pt2((rho / img2.rows*sin(theta)) / cos(theta), img2.rows);
line(img, pt1, pt2, Scalar(255), 1);
}
else
{
Point pt1(0, rho / sin(theta));
Point pt2(img2.cols, (rho - img2.cols*cos(theta)) / sin(theta));
line(img, pt1, pt2, Scalar(0,255,0), 1,LINE_8);
}
++it;
}


imshow("image", img);


Mat img3;
img3.create(img.size(), img.type());
cvtColor(img, img3, CV_RGB2GRAY);
equalizeHist(img3, img3);
blur(img3, img3, Size(3,3));
Canny(img3, img3, 100, 150);
threshold(img3, img3, 0, 255, CV_THRESH_OTSU);
imshow("imagw3", img3);
waitKey();
return 0;
}


这个程序的结果就是讲一个马路的线进行特征提取。因为本星期一直再看深度学习的书,所以那本算法书没有仔细的去看,不能瞎提出坑害读者


东西很简单,因为基本上没有opencv写过东西,所以我就算一种尝试了吧!

原创粉丝点击