c++/OpenCv 边缘识别

qq_38242442 2018-01-11 09:46:32
我的代码如下:
#include<iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

#define binaryname "二值图"
#define binarytrack "二值图阈值"
#define copy "二维数组存储图"
#define newdel "微分边缘化"
IplImage *src;
IplImage *binary;
IplImage *copy1;
IplImage *copy2;
void on_trackbar(int pos);


int main(int argc, char* argv[])
{
//载入原图的灰度图并显示
src = cvLoadImage("F:\\Pictrue\\picturefortest\\bmp.bmp", 0);
cvNamedWindow("source", 1);
cvShowImage("source", src);

int m = src->height;//行
int n = src->width;//列
int i, j;
printf("channel = %d", src->nChannels);//显示通道数

//创建动态指针
int **p;
int **p2;
p = new int *[m];
p2 = new int *[m];
for (i = 0; i < m; i++)
{
p[i] = new int[n];
p2[i] = new int[n - 1];
}



//初始化二值图并创建窗口
binary = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);//创建二值图
cvNamedWindow(binaryname, CV_WINDOW_AUTOSIZE);//创建二值图窗口

//创建滑动条
int nThreshold;
cvCreateTrackbar(binarytrack, binaryname, &nThreshold, 255, on_trackbar);
on_trackbar(nThreshold);//执行回调函数,转化二值图像


//获取binary像素信息并保存
CvScalar s;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
s = cvGet2D(binary, i, j);//CvGet2D函数作用:获取图像的颜色值
p[i][j] = s.val[0];
}
}

//显示保存的像素信息
copy1 = cvCreateImage(cvGetSize(binary), 8, 1);
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
cvSetReal2D(copy1, i, j, p[i][j]);
}
}
cvNamedWindow(copy, 1);
cvShowImage(copy, copy1);

//微分边缘化,结果存进新数组
for (i = 0; i < m; i++)
{
for (j = 0; j < n - 1; j++)
{
if (p[i][j + 1] > p[i][j])
p2[i][j] = p[i][j + 1] - p[i][j];
else
{
p2[i][j] = -(p[i][j + 1] - p[i][j]);
}

}
}

//显示微分后的新数组
IplImage *copy2 = cvCreateImage(cvGetSize(binary), 8, 1);
for (i = 0; i < m; i++)
{
for (j = 0; j < n - 1; j++)
{
cvSetReal2D(copy2, i, j, p2[i][j]);
}
}
cvNamedWindow(newdel, 1);
cvShowImage(newdel, copy2);

cvWaitKey();
cvReleaseImage(&src);
cvReleaseImage(©1);
cvReleaseImage(©2);
cvReleaseImage(&binary);
cvDestroyAllWindows();

for (i = 0; i < m; i++)
{
delete[] p[i];
delete[] p2[i];
}
delete[] p;
delete[] p2;

return 0;
}
//回调函数 将灰度图转化为二值图并显示
void on_trackbar(int pos)
{
cvThreshold(copy1, binary, pos, 255, CV_THRESH_BINARY);//转化为二值图
cvShowImage(binaryname, binary);
printf("channel = %d", binary->nChannels);
}

遇到的问题:

请问这个问题该怎么解决?谢谢!
...全文
813 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-02-05
  • 打赏
  • 举报
回复
引用 9 楼 qq_38242442 的回复:
这帖子能捞吗 我的问题还没解决啊。。。
QQ:511606848 QQ远程桌面帮你解决。
qq_38242442 2018-02-02
  • 打赏
  • 举报
回复
这帖子能捞吗 我的问题还没解决啊。。。
赵4老师 2018-01-15
  • 打赏
  • 举报
回复
仅供参考:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgproc/imgproc_c.h"
using namespace std;
using namespace cv;
Mat img,smallImg,gray,bw;
vector<Vec4i> hierarchy;
vector<vector<Point> > contours;
int threshval=128;
Rect r;
Rect maxrect,brect;
int idx,n;
const static Scalar colors[15]={
    CV_RGB(  0,  0,128),
    CV_RGB(  0,128,  0),
    CV_RGB(  0,128,128),
    CV_RGB(128,  0,  0),
    CV_RGB(128,  0,128),
    CV_RGB(128,128,  0),
    CV_RGB(128,128,128),
    CV_RGB(160,160,160),
    CV_RGB(  0,  0,255),
    CV_RGB(  0,255,  0),
    CV_RGB(  0,255,255),
    CV_RGB(255,  0,  0),
    CV_RGB(255,  0,255),
    CV_RGB(255,255,  0),
    CV_RGB(255,255,255),
};
Scalar color;
void gamma_correct(Mat& img, Mat& dst, double gamma) {
	Mat	temp;
	CvMat tmp;

	img.convertTo(temp,	CV_32FC1, 1.0/255.0, 0.0);
	tmp=temp;
	cvPow(&tmp,	&tmp, gamma);
	temp.convertTo(dst , CV_8UC1 , 255.0	, 0.0);
}
int main() {
    cvNamedWindow("display",1);
    img=imread("image.jpg",1);
    r.x=img.cols/10;
    r.y=img.rows/3;
    r.width=img.cols*8/10;
    r.height=img.rows*2/3;
    smallImg=img(r);
    cvtColor(smallImg,gray,CV_BGR2GRAY);
//  medianBlur(gray,gray,5);
    equalizeHist(gray,gray);
    gamma_correct(gray,gray,4.0);
    imshow("display",gray);
    waitKey(0);

	bw=(gray>threshval);
    imshow("display",bw);
    waitKey(0);

	Mat	Structure0=getStructuringElement(MORPH_RECT,Size(3,3));
    erode(bw,bw,Structure0,Point(-1,-1));
	Mat	Structure1=getStructuringElement(MORPH_RECT,Size(6,6));
    dilate(bw,bw,Structure1, Point(-1,-1));
    imshow("display",bw);
    waitKey(0);

    findContours(bw,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);
    if (!contours.empty()&&!hierarchy.empty()) {
        idx=0;
        n=0;
        vector<Point> approx;
        for (;idx>=0;idx=hierarchy[idx][0]) {
            color=colors[idx%15];
//          drawContours(smallImg,contours,idx,color,1,8,hierarchy);
            approxPolyDP(Mat(contours[idx]), approx, arcLength(Mat(contours[idx]), true)*0.005, true);//0.005为将毛边拉直的系数
            const Point* p = &approx[0];
            int m=(int)approx.size();
            polylines(smallImg, &p, &m, 1, true, color);
            circle(smallImg,Point(p[0].x,p[0].y),3,color);
            circle(smallImg,Point(p[1].x,p[1].y),2,color);
			for	(int i=2;i<m;i++) circle(smallImg,Point(p[i].x,p[i].y),1,color);
            n++;
            if (1==n) {
                maxrect=boundingRect(Mat(contours[idx]));
            } else {
                brect=boundingRect(Mat(contours[idx]));
                CvRect mr(maxrect),br(brect);
                maxrect=cvMaxRect(&mr,&br);
            }
        }
        circle(smallImg,Point(maxrect.x+maxrect.width/2,maxrect.y+maxrect.height/2),2,CV_RGB(255,0,0));
    }
    imshow("display",smallImg);
    waitKey(0);
    cvDestroyWindow("display");
    return 0;
}
kuangbao9 2018-01-12
  • 打赏
  • 举报
回复
引用 2 楼 qq_38242442 的回复:
[quote=引用 1 楼 kuangbao9 的回复:] void on_trackbar(int pos) { cvThreshold(copy1, binary, pos, 255, CV_THRESH_BINARY);//转化为二值图 cvShowImage(binaryname, binary); printf("channel = %d", binary->nChannels); } 你调用回调函数时,copy1还没有吧?当然会报错
啊搞错了,,但是我把copy1改成了src,运行还是这个错误。我点中断后出现的是“无可用源”[/quote]
引用 2 楼 qq_38242442 的回复:
[quote=引用 1 楼 kuangbao9 的回复:] void on_trackbar(int pos) { cvThreshold(copy1, binary, pos, 255, CV_THRESH_BINARY);//转化为二值图 cvShowImage(binaryname, binary); printf("channel = %d", binary->nChannels); } 你调用回调函数时,copy1还没有吧?当然会报错
啊搞错了,,但是我把copy1改成了src,运行还是这个错误。我点中断后出现的是“无可用源”[/quote] 该不是你图片路径错了吧?你把图片拷贝到当前目录下试试
qq_38242442 2018-01-12
  • 打赏
  • 举报
回复
引用 6 楼 kuangbao9 的回复:
还有。你把nThreshold初始化一下
绝望,,还是不行。依然是那个错误。难道是要更改什么配置吗。
kuangbao9 2018-01-12
  • 打赏
  • 举报
回复
还有。你把nThreshold初始化一下
kuangbao9 2018-01-12
  • 打赏
  • 举报
回复
额,把copy1改成src,在我这可以完美运行,问题可能就出在你加载的图片上。你在网上下个jpg的试试。
qq_38242442 2018-01-12
  • 打赏
  • 举报
回复
引用 3 楼 kuangbao9 的回复:
[quote=引用 2 楼 qq_38242442 的回复:]
[quote=引用 1 楼 kuangbao9 的回复:]
void on_trackbar(int pos)
{
cvThreshold(copy1, binary, pos, 255, CV_THRESH_BINARY);//转化为二值图
cvShowImage(binaryname, binary);
printf("channel = %d", binary->nChannels);
}
你调用回调函数时,copy1还没有吧?当然会报错

啊搞错了,,但是我把copy1改成了src,运行还是这个错误。我点中断后出现的是“无可用源”[/quote]

引用 2 楼 qq_38242442 的回复:
[quote=引用 1 楼 kuangbao9 的回复:]
void on_trackbar(int pos)
{
cvThreshold(copy1, binary, pos, 255, CV_THRESH_BINARY);//转化为二值图
cvShowImage(binaryname, binary);
printf("channel = %d", binary->nChannels);
}
你调用回调函数时,copy1还没有吧?当然会报错

啊搞错了,,但是我把copy1改成了src,运行还是这个错误。我点中断后出现的是“无可用源”[/quote]

该不是你图片路径错了吧?你把图片拷贝到当前目录下试试
[/quote]
不是的 我试过了,还是会有这个问题。而且我之前忘记贴这个了,上面有提到错误原因:

OpenCV Error: Assertion failed (src.size == dst.size && src.channels() == dst.channels() && (src.depth() == dst.depth() || dst.depth() == CV_8U)) in cvThreshold, file C:\builds\master_PackSlave-win32-vc12-shared\opencv\modules\imgproc\src\thresh.cpp, line 1343

我百度了一下说是要检查是否初始化,输入输出图像矩阵大小,输入输出图像的深度是否一样。难道问题出在图像深度上?但我好像并没有找出哪里不对的。。
qq_38242442 2018-01-11
  • 打赏
  • 举报
回复
引用 1 楼 kuangbao9 的回复:
void on_trackbar(int pos)
{
cvThreshold(copy1, binary, pos, 255, CV_THRESH_BINARY);//转化为二值图
cvShowImage(binaryname, binary);
printf("channel = %d", binary->nChannels);
}
你调用回调函数时,copy1还没有吧?当然会报错

啊搞错了,,但是我把copy1改成了src,运行还是这个错误。我点中断后出现的是“无可用源”
kuangbao9 2018-01-11
  • 打赏
  • 举报
回复
void on_trackbar(int pos) { cvThreshold(copy1, binary, pos, 255, CV_THRESH_BINARY);//转化为二值图 cvShowImage(binaryname, binary); printf("channel = %d", binary->nChannels); } 你调用回调函数时,copy1还没有吧?当然会报错

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧