横竖弯曲边缘的交点(类改写)(第二个类)

来源:互联网 发布:淘宝店铺首页怎么装修 编辑:程序博客网 时间:2024/04/27 23:16

我的:


其中具体是:

#include "corner_finder.h"corner_finder::corner_finder(IplImage *srcimg){src = srcimg;flag = NULL;x = NULL;y = NULL;corner_left_min = src->width*0.2;corner_right_max = src->width*0.8;corner_up_min = src->height*0.2;corner_down_max = src->height*0.8;src_gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);cvCvtColor(src, src_gray, CV_BGR2GRAY);cvThreshold(src_gray, src_gray, 25, 255, 0);}Point corner_finder::finder_predone(){//cvSaveImage("thresh.bmp", src_gray);//上面是准备工作 vector<KeyPoint> train_keyPoint;SiftFeatureDetector featureDetector;featureDetector.detect(src_gray, train_keyPoint);vector<Point> corners_all;int y_min = src_gray->height - 1, x_min = src_gray->width - 1;Point myleft, myup, result_corner;for (size_t j = 0; j < train_keyPoint.size(); j++){KeyPoint kp1 = train_keyPoint[j];Point2f kpp1 = kp1.pt;Point mypt1(cvRound(kpp1.x), cvRound(kpp1.y));if (mypt1.y <= y_min){y_min = mypt1.y;myup = mypt1;}if (mypt1.x <= x_min){x_min = mypt1.x;myleft = mypt1;}}result_corner = Point(myup.x, myleft.y);return result_corner;}void corner_finder::find_corner(){int step = src_gray->widthStep / sizeof(uchar);uchar* data = (uchar*)src_gray->imageData;uchar temp;int ii = src_gray->height - 1;int flag_row = 1;for (int j = 0; j < src_gray->width; j++){temp = data[ii*step + j*src_gray->nChannels + 0];if (temp == 0){flag_row = 0;break;}}int j = src_gray->width - 1;int flag_col = 1;for (int i = 0; i < src_gray->height; i++){temp = data[i*step + j*src_gray->nChannels + 0];if (temp == 0){flag_col = 0;break;}}/////////////////////////////////////////////if (flag_col == 1){//第一种情况 判断全白int jj = 0;int flag_firstcol = 0;for (int i = 0; i < src_gray->height; i++){temp = data[i*step + jj*src_gray->nChannels + 0];if (temp == 0){flag_firstcol = 1;break;}}if (flag_firstcol == 0)flag = 2;else{if (flag_row == 1){Point result = finder_predone();if ((result.x >= corner_left_min && result.x <= corner_right_max) && (result.y >= corner_up_min && result.y <= corner_down_max)){x = result.x;y = result.y;return;}if (result.x < corner_left_min){flag = 4;return;}if (result.x > corner_right_max){flag = 2;return;}if (result.y < corner_up_min){flag = 5;return;}if (result.y > corner_down_max){flag = 3;return;}}elseflag = 3;}}elseflag = 1;}void corner_finder::print_result(){cout << "flag: " << flag << " x: " << x << " y: " << y << endl;}myresult corner_finder::get_corner(){myresult corners;corners.resultflag = flag;corners.resultx = x;corners.resulty = y;return corners;}corner_finder::~corner_finder(){}
这是类实现  接着是类测试:

#include "corner_finder.h"#include <fstream>using namespace std;char srcfile[100];void main(){///////////////////////////////////////////////////////所有生态图 将提示转为返回值 返回都是int 存为csv文件ofstream file("corner_result2.csv");for (int i = 1; i <= 66; i++){sprintf(srcfile, "生态图小图\\%d.bmp", i);IplImage* src = cvLoadImage(srcfile, CV_LOAD_IMAGE_UNCHANGED);corner_finder mycorner(src);Point nouse = mycorner.finder_predone();mycorner.find_corner();//mycorner.print_result();myresult finalcorner = mycorner.get_corner();if (finalcorner.resultflag==0)file << srcfile << "    " << finalcorner.resultx << "," << finalcorner.resulty << "\n";elsefile << srcfile << "    " << finalcorner.resultflag << "\n";}}
测试结果和上几篇写过的 结果一致  证明正确   请教同事帮我提出缺点 3个:构造在循环内部导致多次重复构造重复申请内存空间 效率低下!第二点 :找角点的准备工作
mycorner.find_corner();
和开始正式找寻角点这两个函数不该分开 因为其实是一个功能  或者说不该是让用户分开调用  用户关心的只是找角点并不想为你做找角点的准备工作  类的实现着可以将两者分开 但不应该设计让类的使用者这样!当然我好傻后面才看到这句不需要 但不需要的最好放在private里 避免给user造成误解 。
myresult finalcorner = mycorner.get_corner();
第三点:学着写注释!
///////////////////////////////////////////////////////////////////////////////////////////////////////////

修改后:


具体实现:

#include "corner_finder.h"corner_finder::corner_finder(){}void corner_finder::setimginfo(IplImage *srcimg){src = srcimg;flag = NULL;x = NULL;y = NULL;corner_left_min = src->width*0.2;corner_right_max = src->width*0.8;corner_up_min = src->height*0.2;corner_down_max = src->height*0.8;src_gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);cvCvtColor(src, src_gray, CV_BGR2GRAY);cvThreshold(src_gray, src_gray, 25, 255, 0);}Point corner_finder::finder_predone(){vector<KeyPoint> train_keyPoint;SiftFeatureDetector featureDetector;featureDetector.detect(src_gray, train_keyPoint);vector<Point> corners_all;int y_min = src_gray->height - 1, x_min = src_gray->width - 1;Point myleft, myup, result_corner;for (size_t j = 0; j < train_keyPoint.size(); j++){KeyPoint kp1 = train_keyPoint[j];Point2f kpp1 = kp1.pt;Point mypt1(cvRound(kpp1.x), cvRound(kpp1.y));if (mypt1.y <= y_min){y_min = mypt1.y;myup = mypt1;}if (mypt1.x <= x_min){x_min = mypt1.x;myleft = mypt1;}}result_corner = Point(myup.x, myleft.y);return result_corner;}void corner_finder::find_corner(){int step = src_gray->widthStep / sizeof(uchar);uchar* data = (uchar*)src_gray->imageData;uchar temp;int ii = src_gray->height - 1;int flag_row = 1;for (int j = 0; j < src_gray->width; j++){temp = data[ii*step + j*src_gray->nChannels + 0];if (temp == 0){flag_row = 0;break;}}int j = src_gray->width - 1;int flag_col = 1;for (int i = 0; i < src_gray->height; i++){temp = data[i*step + j*src_gray->nChannels + 0];if (temp == 0){flag_col = 0;break;}}if (flag_col == 1){int jj = 0;int flag_firstcol = 0;for (int i = 0; i < src_gray->height; i++){temp = data[i*step + jj*src_gray->nChannels + 0];if (temp == 0){flag_firstcol = 1;break;}}if (flag_firstcol == 0)flag = 2;else{if (flag_row == 1){Point result = finder_predone();if ((result.x >= corner_left_min && result.x <= corner_right_max) && (result.y >= corner_up_min && result.y <= corner_down_max)){x = result.x;y = result.y;return;}if (result.x < corner_left_min){flag = 4;return;}if (result.x > corner_right_max){flag = 2;return;}if (result.y < corner_up_min){flag = 5;return;}if (result.y > corner_down_max){flag = 3;return;}}elseflag = 3;}}elseflag = 1;}void corner_finder::print_result(){cout << "flag: " << flag << " x: " << x << " y: " << y << endl;}myresult corner_finder::get_corner(){myresult corners;corners.resultflag = flag;corners.resultx = x;corners.resulty = y;return corners;}corner_finder::~corner_finder(){}
下面是测试的:

#include "corner_finder.h"#include <fstream>using namespace std;char srcfile[100];void main(){////////////////////所有生态图 将提示转为返回值 返回都是int 存为csv文件ofstream file("corner_result4.csv");corner_finder mycorner;for (int i = 1; i <= 66; i++){sprintf(srcfile, "生态图小图\\%d.bmp", i);IplImage* src = cvLoadImage(srcfile, CV_LOAD_IMAGE_UNCHANGED);mycorner.setimginfo(src);mycorner.find_corner();mycorner.print_result(); //打印至屏幕//将角点结果保存到csv文件myresult finalcorner = mycorner.get_corner();if (finalcorner.resultflag==0)file << srcfile << "    " << finalcorner.resultx << "," << finalcorner.resulty << "\n";elsefile << srcfile << "    " << finalcorner.resultflag << "\n";}}
看来自己要学习的还有很多  要慢慢养成良好的面向对象编程习惯和设计方式!


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

将其移植到虚拟机上:

除了上一篇那样在编译project时setting添加库和头文件以外;还要将这些lib写进linux系统lib64里面 否则会报错:


通过终端写进lib64里面:同事说这叫做创建软链接 前面的目录里有libopencv_photo但后面的linux的lib64里没有 这样创建软链接后就有了。

在运行时 如果要读图片 这个图片文件夹应该这样放置 就直接放在工程目录下就OK:它就读到了 并输出了结果。所以这个可以证明:默认当前工作目录就是工程项目的下一级  我将结果保存看它生成的文件在哪里一样可以证明这一点:看这个csv文件保存在了src的同级目录下:同样证明了这一点!

////////////////////////////////////////////////////////////////////////////////////////////

另外一点差点忘记了  linux下的 不可以void main(){}必须有返回值  所以还是用int main(){return 0;}这样好了!










/////////////////////////////////裸数据转成图片//////////////////////////////////////////

IplImage* src = cvLoadImage("4.bmp");uchar* datasrc = (uchar*)src->imageData; //裸数据指针//提供uchar*类型的图像像素指针CvSize mysize = cvSize(612, 512);IplImage *dst = cvCreateImage(mysize, IPL_DEPTH_8U, 3);uchar* datadst = (uchar*)dst->imageData;/* // 第一种 一个一个拿像素值int dststep = dst->widthStep / sizeof(uchar);int dstchannels = dst->nChannels;for (int i = 0; i < dst->height; i++)for (int j = 0; j < dst->width; j++){datadst[i*dststep + j*dstchannels + 0] = datasrc[i*dststep + j*dstchannels + 0];datadst[i*dststep + j*dstchannels + 1] = datasrc[i*dststep + j*dstchannels + 1];datadst[i*dststep + j*dstchannels + 2] = datasrc[i*dststep + j*dstchannels + 2];}*///第二种  一下拿指向所有像素的指针dst->imageData = (char*)datasrc;//显示裸数据转成的图片dstcvShowImage("exam", dst);cvSaveImage("exam.bmp", dst);cvWaitKey(0);


0 0