大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全家桶1年46,售后保障稳定
这其实是一个小工程
完成的功能:
-
使用摄像头采集图像进行预处理(检测部分)
-
提取出预处理的条形码图像(识别部分)
-
将条形码进行存入数据库(存储部分)
首先接到这个图像识别的小工程需要先确定这个工程的最初输入,和最后输出,输入就是普通的RGB图像,输出是数据库文件。
其中需要完成的过程,就是我需要做得功能,检测部分、识别部分和存储部分,话不多说,上部分代码:
//检测部分 需要用到opencv开源计算机视觉库
//输入是RGB 输出是保存的检测部分
Mat Check(Mat image)
{
vector<vector<Point>> contours;
vector<Vec4i> hiera;
imshow("原图", image);
//原图像大小调整,提高运算效率
//resize(image, image, Size(500, 300));
//imshow("原图像", image); waitKey(15); system("pause");
//转化为灰度图
cvtColor(image, imageGray, CV_RGB2GRAY);
//imshow("灰度图", imageGray); waitKey(15); system("pause");
//高斯平滑滤波
GaussianBlur(imageGray, imageGuussian, Size(3, 3), 0);
//imshow("高斯平衡滤波", imageGuussian); waitKey(15); system("pause");
//求得水平和垂直方向灰度图像的梯度差,使用Sobel算子
Mat imageX16S, imageY16S;
Sobel(imageGuussian, imageX16S, CV_16S, 1, 0, 3, 1, 0, 4);
Sobel(imageGuussian, imageY16S, CV_16S, 0, 1, 3, 1, 0, 4);
convertScaleAbs(imageX16S, imageSobelX, 1, 0);
convertScaleAbs(imageY16S, imageSobelY, 1, 0);
imageSobelOut = imageSobelX - imageSobelY;
//imshow("X方向梯度", imageSobelX); waitKey(15); system("pause");
//imshow("Y方向梯度", imageSobelY); waitKey(15); system("pause");
//imshow("XY方向梯度差", imageSobelOut); waitKey(15); system("pause");
//均值滤波,消除高频噪声
blur(imageSobelOut, imageSobelOut, Size(3, 3));
//imshow("均值滤波", imageSobelOut); waitKey(15); system("pause");
//二值化
Mat imageSobleOutThreshold;
threshold(imageSobelOut, imageSobleOutThreshold, 100, 255, CV_THRESH_BINARY);
//imshow("二值化", imageSobleOutThreshold); waitKey(15); system("pause");
//闭运算,填充条形码间隙
Mat element = getStructuringElement(1, Size(9, 9));
morphologyEx(imageSobleOutThreshold, imageSobleOutThreshold, MORPH_CLOSE, element);
//imshow("闭运算", imageSobleOutThreshold); waitKey(15); system("pause");
//腐蚀,去除孤立的点
erode(imageSobleOutThreshold, imageSobleOutThreshold, element);
//imshow("腐蚀", imageSobleOutThreshold); waitKey(15); system("pause");
//膨胀,填充条形码间空隙,根据核的大小,有可能需要2~3次膨胀操作
dilate(imageSobleOutThreshold, imageSobleOutThreshold, element);
dilate(imageSobleOutThreshold, imageSobleOutThreshold, element);
dilate(imageSobleOutThreshold, imageSobleOutThreshold, element);
//dilate(imageSobleOutThreshold, imageSobleOutThreshold, element);
//dilate(imageSobleOutThreshold, imageSobleOutThreshold, element);
//dilate(imageSobleOutThreshold, imageSobleOutThreshold, element);
//imshow("膨胀", imageSobleOutThreshold); waitKey(30); system("pause");
return imageSobleOutThreshold;
}
int main(int argc, char *argv[])
{
...;
//测试用
//image = imread("1.jpg");
//定义两个容器去存放矩形区域
vector<vector<Point>> contours;
vector<Vec4i> hiera;
imshow("原图", image);
findContours(Check(image), contours, hiera, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
for (int i = 0; i < contours.size(); i++)
{
Rect rect = boundingRect((Mat)contours[i]);
rectangle(image, rect, Scalar(255), 2);
Mat ROI = image(rect);
sprintf(filenameIfZbar, "G:\\using\\text\\vs\\work\\zbar\\if1weima\\%d.jpg", i);
//imshow(filename, rect);
imwrite(filenameIfZbar, ROI);
//imshow("ROI",image); waitKey(30); system("pause");
waitKey(1000); // 等待按下esc键,若需要延时1s则改用waitKey(1000);
...;
}
...;
}
检测效果图,已经存入图像图:
识别部分输入是保存的检测为条形码区域图像,输出是一维码图像,部分代码:
int main(int argc, char *argv[])
{
...;
for (int i = 0; i < contours.size(); i++)
{
...;
temp = image;
cvtColor(temp, imageGray, CV_RGB2GRAY);
//imshow("灰度图", imageGray);
// 获取所摄取图像的长和宽
int width = imageGray.cols;
int height = imageGray.rows;
// 在Zbar中进行扫描时候,需要将OpenCV中的Mat类型转换为(uchar *)类型,raw中存放的是图像的地址;对应的图像需要转成Zbar中对应的图像zbar::Image
uchar *raw = (uchar *)imageGray.data;
Image imageZbar(width, height, "Y800", raw, width * height);
// 扫描相应的图像imageZbar(imageZbar是zbar::Image类型,存储着读入的图像)
scanner.scan(imageZbar); //扫描条码
Image::SymbolIterator symbol = imageZbar.symbol_begin();
if (imageZbar.symbol_begin() == imageZbar.symbol_end())
{
cout << "查询条码失败,请检查图片!" << endl;
//system(delFile);
continue;
}
for (; symbol != imageZbar.symbol_end(); ++symbol)
{
string type, data;
type = symbol->get_type_name();
data = symbol->get_data();
cout << "类型:" << endl << type << endl << endl;
cout << "条码:" << endl << data << endl << endl;
sprintf(filenameIsZbar, "G:\\using\\text\\vs\\work\\zbar\\is1weima\\_%s_%s.jpg", type.c_str(), data.c_str());
//imshow(filename, rect);
imwrite(filenameIsZbar, ROI);
...;
}
waitKey(1000); // 等待按下esc键,若需要延时1s则改用waitKey(1000);
}
...;
}
效果图:
识别完成的图像进行存储,部分代码+效果图:
int main(int argc, char *argv[])
{
...;
for (int i = 0; i < contours.size(); i++)
{
...;
for (; symbol != imageZbar.symbol_end(); ++symbol)
{
...;
//表data写入数据
sprintf(filedir, "..\\is1weima\\_%s_%s.jpg", type.c_str(), data.c_str());
sprintf(csql_table1, "INSERT INTO [zbar].[dbo].[data]([type],[data],[imag]) VALUES('%s','%s','%s')", type.c_str(), data.c_str(), filedir);
Sql = csql_table1;
try{
_RecordsetPtr pRst(__uuidof(Recordset)); //实例化一个Recordset对象pRst
_CommandPtr pCmd(__uuidof(Command)); //实例化一个Command对象pCmd
pCmd->put_ActiveConnection(_variant_t((IDispatch*)pConnection));
pCmd->CommandText = (_bstr_t)Sql;
pRst = pCmd->Execute(NULL, NULL, adCmdText);
cout << "添加成功!" << endl;
pRst.Release();
pCmd.Release();
}
catch (_com_error e) {
cout << e.ErrorMessage() << endl;
cout << "添加失败!" << endl;
}
//表num写入数据
try {
sprintf(csql_table2, "select count(%s) [data] from [zbar].[dbo].[data]group by [data]", data.c_str());
Sql = csql_table2;
//_variant_t value;
_RecordsetPtr pRst(__uuidof(Recordset)); //实例化一个Recordset对象pRst
_CommandPtr pCmd(__uuidof(Command)); //实例化一个Command对象pCmd
pCmd->put_ActiveConnection(_variant_t((IDispatch*)pConnection));
pCmd->CommandText = (_bstr_t)Sql;
pRst = pCmd->Execute(NULL, NULL, adCmdText);
int valueline = pRst->GetCollect("data");
//update [zbar].[dbo].[data] set [data]='12456'where [imag]='..\is1weima\_EAN-13_4589732812540.jpg
cout << "查询成功!" << endl;
sprintf(csql_table3, "update [zbar].[dbo].[num] set [num]='%d'where [data]='%s'", valueline, data.c_str());
Sql = csql_table3;
pCmd->put_ActiveConnection(_variant_t((IDispatch*)pConnection));
pCmd->CommandText = (_bstr_t)Sql;
pRst = pCmd->Execute(NULL, NULL, adCmdText);
cout << "修改成功!" << endl;
pRst.Release();
pCmd.Release();
}
catch (_com_error e) {
//cout << e.ErrorMessage() << endl;
//cout << "修改失败!" << endl;
sprintf(csql_table1, "INSERT INTO [zbar].[dbo].[num]([type],[data],[num]) VALUES('%s','%s','%d')", type.c_str(), data.c_str(), 1);
Sql = csql_table1;
_RecordsetPtr pRstR(__uuidof(Recordset)); //实例化一个Recordset对象pRst
_CommandPtr pCmdR(__uuidof(Command)); //实例化一个Command对象pCmd
pCmdR->put_ActiveConnection(_variant_t((IDispatch*)pConnection));
pCmdR->CommandText = (_bstr_t)Sql;
pRstR = pCmdR->Execute(NULL, NULL, adCmdText);
cout << "添加成功!" << endl;
pRstR.Release();
pCmdR.Release();
}
}
waitKey(1000); // 等待按下esc键,若需要延时1s则改用waitKey(1000);
}
...;
}
工程已上传,审核中…
审核通过OpenCV识别多条形码链接
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/223795.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...