版主用的相机是小觅相机,opencv环境和cmake也是匹配好的
参考添加链接描述
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include
using namespace cv;
using namespace std;
Mat src;
Mat src_gray;
RNG rng(12345);
//Scalar colorful = CV_RGB(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
Point Center_cal(vector > contours, int i)//找到所提取轮廓的中心点
{
int centerx = 0, centery = 0, n = contours[i].size();
//在提取的小正方形的边界上每隔周长个像素提取一个点的坐标,求所提取四个点的平均坐标(即为小正方形的大致中心)
centerx = (contours[i][n / 4].x + contours[i][n * 2 / 4].x + contours[i][3 * n / 4].x + contours[i][n - 1].x) / 4;
centery = (contours[i][n / 4].y + contours[i][n * 2 / 4].y + contours[i][3 * n / 4].y + contours[i][n - 1].y) / 4;
Point point1 = Point(centerx, centery);
return point1;
}
int main(int argc, char const* argv[])
{
// src = imread("/home/dzy/MYNT-EYE-D-SDK/samples/src/imgs/aaa.jpg");
src = imread("/home/dzy/MYNT-EYE-D-SDK/samples/src/imgs/weixin.png");
// 图片的缩小
// Mat dstImage1;
// Mat tempImage = src;
// resize( tempImage, dstImage1, Size(tempImage.cols/4, tempImage.rows/4), 0, 0, INTER_NEAREST );
// imshow("er_src", dstImage1);
Mat src_all = src.clone();
cvtColor(src, src_gray, CV_BGR2GRAY);
blur(src_gray, src_gray, Size(3, 3));//均值滤波
// equalizeHist(src_gray, src_gray);
// imshow("lvbo_hou", src_gray);
Scalar color = Scalar(1, 1, 255);
Mat threshold_output;
vector hierarchy;
Mat drawing = Mat::zeros(src.size(), CV_8UC3);
Mat drawing2 = Mat::zeros(src.size(), CV_8UC3);
threshold(src_gray, threshold_output, 112, 255, THRESH_BINARY);
// imshow("threshold_output", threshold_output);
//Canny(src_gray,threshold_output,136,196,3);
//imshow("预处理后:",threshold_output);
//寻找轮廓
//第一个参数是输入图像 2值化的
//第二个参数是内存存储器,FindContours找到的轮廓放到内存里面。
//第三个参数是层级,**[Next, Previous, First_Child, Parent]** 的vector
//第四个参数是类型,采用树结构
//第五个参数是节点拟合模式,这里是全部寻找
vector > contours, contours2;
findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0));
//CHAIN_APPROX_NONE全体,CV_CHAIN_APPROX_SIMPLE,,,RETR_TREE RETR_EXTERNAL RETR_LIST RETR_CCOMP
int c = 0, ic = 0, k = 0, area = 0;
//程序的核心筛选
int parentIdx = -1;
for (int i = 0; i < contours.size(); i++)
{
if (hierarchy[i][2] != -1 && ic == 0)
{
parentIdx = i;
ic++;
}
else if (hierarchy[i][2] != -1)
{
ic++;
}
else if (hierarchy[i][2] == -1)
{
ic = 0;
parentIdx = -1;
}
if (ic >= 2)
{
contours2.push_back(contours[parentIdx]);
drawContours(drawing, contours, parentIdx,Scalar(1, 1, 255), 1, 8);
ic = 0;
parentIdx = -1;
area = contourArea(contours[i]);//得出一个二维码定位角的面积,以便计算其边长(area_side)(数据覆盖无所谓,三个定位角中任意一个数据都可以)
}
}
for (int i = 0; i < contours2.size(); i++)
drawContours(drawing2, contours2, i, CV_RGB(rng.uniform(100, 255), rng.uniform(100, 255), rng.uniform(100, 255)), -1, 4, hierarchy[k][2], 0, Point());
Point point[3];
for (int i = 0; i < contours2.size(); i++)
{
point[i] = Center_cal(contours2, i);
}
if (!contours2.empty() && contours2.size()>2){
vector &vector_t = contours2[1];
if (!vector_t.empty() && vector_t.size()>1){
area = contourArea(vector_t);//为什么这一句和前面一句计算的面积不一样呢
int area_side = cvRound(sqrt(double(area)));
for (int i = 0; i < contours2.size(); i++)
{
line(drawing2, point[i%contours2.size()], point[(i + 1) % contours2.size()], color, area_side / 4, 8);
}
// imshow("tiqu_hou", drawing2);
// printf("%d\n", contours.size());
// imshow( "Contours", drawing );
//接下来要框出这整个二维码
Mat gray_all, threshold_output_all;
vector > contours_all;
vector hierarchy_all;
cvtColor(drawing2, gray_all, CV_BGR2GRAY);
// imshow( "gray_all", gray_all );
threshold(gray_all, threshold_output_all, 45, 255, THRESH_BINARY);
// imshow( "threshold_output_all", threshold_output_all );
//表示只寻找出来连线的最外层轮廓
findContours(threshold_output_all, contours_all, hierarchy_all, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0));//RETR_EXTERNAL表示只寻找最外层轮廓
//求最小包围矩形,斜的也可以哦
RotatedRect rectPoint = minAreaRect(contours_all[0]);
Point2f fourPoint2f[4];
//将rectPoint变量中存储的坐标值放到 fourPoint的数组中
rectPoint.points(fourPoint2f);
for (int i = 0; i < 4; i++)
{
line(src_all, fourPoint2f[i % 4], fourPoint2f[(i + 1) % 4], Scalar(1, 1, 255), 3);
}
/**
* 图片截取
* */
int threshold_val = 20;
Mat img = src;
Mat dst;
Mat roi = Mat::zeros(img.size(),CV_8U);
vector> contour;
vector pts;
pts.emplace_back(Point( fourPoint2f[0].x-threshold_val,fourPoint2f[0].y+threshold_val));//左下角坐标
pts.emplace_back(Point( fourPoint2f[1].x-threshold_val,fourPoint2f[1].y-threshold_val));//左上角坐标
pts.emplace_back(Point( fourPoint2f[2].x+threshold_val,fourPoint2f[2].y-threshold_val));//右上角坐标
pts.emplace_back(Point( fourPoint2f[3].x+threshold_val,fourPoint2f[3].y+threshold_val));//右下角坐标
contour.push_back(pts);
drawContours(roi,contour,0,Scalar::all(255),-1);
img.copyTo(dst,roi);
imshow("dst",dst);
imwrite("../../src/out_ers/caijian1.png",dst);
imshow("erweima", src_all);
}
}
waitKey(0);
return(0);
}
参考: https://blog.csdn.net/Kano365/article/details/89636188
我在编译zbar时正常通过,在执行时出现错误--------------------- zbarcam: error while loading shared libraries: libzbar.so.0: cannot open shared object file: No such file or directory
查阅了一下资料:
https://blog.csdn.net/Visrul/article/details/80406830
https://blog.csdn.net/starelegant/article/details/77869792
都没有找到合适的解决办法,最终在/usr/local/lib目录下执行终端窗口执行ldconfig命令,执行通过~ 原因可能为刚安装的zbar库动态链接并没有加载的缓存文件中需要执行ldconfig命令。
如果共享库文件安装到了/lib或/usr/lib目录下, 那么需执行一下ldconfig命令
ldconfig命令的用途, 主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下, 搜索出可共享的动态链接库(格式如lib*.so*), 进而创建出动态装入程序(ld.so)所需的连接和缓存文件. 缓存文件默认为/etc/ld.so.cache, 此文件保存已排好序的动态链接库名字列表.
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
zbar::ImageScanner scanner;
scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
cv::Mat img = cv::imread("/home/dzy/MYNT-EYE-D-SDK/samples/src/imgs/weixin.png");
cv::Mat imgGray;
imgGray.create(img.size(), CV_8UC1);
cvtColor(img, imgGray, CV_BGR2GRAY);
int width = imgGray.cols;
int height = imgGray.rows;
zbar::Image image(width, height, "Y800", imgGray.data, width *height);
int n = scanner.scan(image);
for (zbar::Image::SymbolIterator symbol = image.symbol_begin();symbol != image.symbol_end();++symbol) {
// cout << "decoded " << symbol->get_type_name()<< " symbol \"" << symbol->get_data() << '"' << endl;
cout << symbol->get_data() << endl;
}
image.set_data(NULL, 0);
return(0);
}
参考链接:https://www.cnblogs.com/lx17746071609/p/11428788.html
源文件.cpp
#include
#include
using namespace cv;
using namespace std;
using namespace zbar;
typedef struct
{
string type;
string data;
vector location;
} decodedObject;
// 查找和解码条形码和二维码
void decode(Mat &im, vector&decodedObjects)
{
// 创建ZBAR扫描器
ImageScanner scanner;
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
// 将图像转换为灰度
Mat imGray;
cvtColor(im, imGray, COLOR_BGR2GRAY);
imshow("gray",imGray);
// 在ZBAR图像中包装图像数据
Image image(im.cols, im.rows, "Y800", (uchar *)imGray.data, im.cols * im.rows);
// 扫描图像中的条形码和二维码
int n = scanner.scan(image);
// 打印输出结果
for (Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol)
{
decodedObject obj;
obj.type = symbol->get_type_name();
obj.data = symbol->get_data();
// Print type and data
cout << "Type : " << obj.type << endl;
cout << "Data : " << obj.data << endl << endl;
// Obtain location
for (int i = 0; i < symbol->get_location_size(); i++)
{
obj.location.push_back(Point(symbol->get_location_x(i), symbol->get_location_y(i)));
}
decodedObjects.push_back(obj);
}
}
// 显示条形码和二维码位置
void display(Mat &im, vector&decodedObjects)
{
// 循环所有解码对象
for (int i = 0; i < decodedObjects.size(); i++)
{
vector points = decodedObjects[i].location;
vector hull;
// 如果这些点不形成四边形,则找到凸包。
if (points.size() > 4)
convexHull(points, hull);
else
hull = points;
// 凸包中的点数
int n = hull.size();
for (int j = 0; j < n; j++)
{
line(im, hull[j], hull[(j + 1) % n], Scalar(255, 0, 0), 3);
}
}
// 显示结果
imshow("Results", im);
waitKey(0);
}
int main(int argc, char* argv[])
{
// Read image
Mat im = imread("/home/dzy/MYNT-EYE-D-SDK/samples/src/imgs/weixin.png");
imshow("Results", im);
// Variable for decoded objects
vector decodedObjects;
// Find and decode barcodes and QR codes
decode(im, decodedObjects);
// Display location
display(im, decodedObjects);
waitKey(0);
return 0;
}
CMakeLists.txt配置
cmake_minimum_required(VERSION 3.13)
project(ercode)
set(CMAKE_CXX_STANDARD 14)
add_executable(ercode main.cpp)
#找到opencv的包
set(TARGET_LIBS "/usr/local/include/opencv2/")
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
#zbar
set(zbar_include_dir "/usr/local/include")
set(zbar_link_dir "/usr/local/lib")
include_directories(${zbar_include_dir})
link_directories(${zbar_link_dir})
link_libraries(zbar)
#动态链接
target_link_libraries(ercode ${OpenCV_LIBS} )
target_link_libraries(ercode jsoncpp)
target_link_libraries(ercode zbar)