如何在 OpenCV 3.0 c++ 中获取链码 xml 文件

How to get the Chain Code xml file in OpenCV 3.0 c++

本文关键字:获取 xml 文件 c++ OpenCV      更新时间:2023-10-16

我正在使用Freeman链代码作为图像的特征提取。我无法读取图像,我需要获取链码 xml 文件。如何检索链码 xml 文件并保存? 下面是我在OpenCV 3.0中的c ++代码有人可以帮忙吗..

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <fstream>
#include<string.h>
using namespace std;
using namespace cv;
int main() {
    Mat img = imread("test.jpg")
    imshow("Test", img);

    vector<vector<Point>> contours; // Vector for storing contour
    vector<Vec4i> hierarchy;

    cv::findContours(img, contours, RETR_EXTERNAL,CV_CHAIN_CODE);
    cout << Mat(contours[0]) << endl;
    findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    cout << "CHAIN_APPROX_SIMPLE" << endl;
    cout << Mat(contours[0]) << endl;
    CvChain* chain = 0;
    CvMemStorage* storage = 0;
    storage = cvCreateMemStorage();
    cvFindContours(&IplImage(img), storage, (CvSeq**)(&chain), sizeof(*chain), CV_RETR_TREE, CV_CHAIN_CODE);
    int total = chain->total;
    cv::Mat hist(1, 8, CV_32F, Scalar(0));
    int totalCount = 0;
    for (; chain != NULL; chain = (CvChain*)chain->h_next)
    {
        int numChain = 0;
        CvSeqReader reader;
        int i, total = chain->total;
        cvStartReadSeq((CvSeq*)chain, &reader, 0);
        cout<<"--------------------chainn";
        for (i = 0; i<total; i++)
        {
            char code;
            CV_READ_SEQ_ELEM(code, reader);
            int Fchain = (int)code;
            hist.at<float>(0, Fchain)++;
            totalCount++;
            cout<<"%d"<<code;
        }
    }
    Mat prob = hist / totalCount;
    cout << prob << endl;
    waitKey(0);
    return 0;
}

每当运行代码时,我都遇到此错误。我是否使用了错误的格式?谁能帮忙?

OpenCV Error: Unsupported format or combination of formats ([Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only) in cvStartFindContours, file C:buildslave64win64_amdoclmaster_PackSlave-win64-vc14-sharedopencvmodulesimgprocsrccontours.cpp, line 198

我已经更新了我的代码。我可以保存 xml 文件,但我只在 1 行中获取数据。

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <fstream>
#include<string.h>
using namespace std;
using namespace cv;
vector<String> files;
int main() {

    double totalCount = 0;
    cv::glob("C:/Users//Videos/Database/Frames/*.jpg", files);
    for (size_t i = 0; i < files.size(); i++) {
        Mat image = imread(files[i]);
        //Mat image = imread("Outline.jpg");
        Canny(image, image, 100, 100 * 2, 3, false);
        CvChain* chain;
        CvMemStorage* storage = 0;
        storage = cvCreateMemStorage();
        cvFindContours(&IplImage(image), storage, (CvSeq**)(&chain), sizeof(*chain), CV_RETR_EXTERNAL, CV_CHAIN_CODE);
        int total = chain->total;

        // 1 row, 8 cols, filled with zeros, (float type, because we want to normalize later):
        cv::Mat hist(1, 8, CV_32F, Scalar(0));
        for (; chain != NULL; chain = (CvChain*)chain->h_next)
        {
            CvSeqReader reader;
            int i, total = chain->total;
            cvStartReadSeq((CvSeq*)chain, &reader, 0);
            for (i = 0; i < total; i++)
            {
                char code;
                CV_READ_SEQ_ELEM(code, reader);
                int Fchain = (int)code;
                // increase the counter for the respective bin:
                hist.at<float>(0, Fchain)++;
                totalCount++;
            }
        }
        // print the raw histogram:
        cout << "Histo: " << hist << endl;
        cout << "Total: " << totalCount << endl;
        // normalize it:
        Mat prob = hist / totalCount;
        cout << "Proba: " << prob << endl;
        FileStorage fs("freeman.xml", FileStorage::WRITE);
        fs << "chain" << prob;
        waitKey(0);
        return 0;
    }
}

如下所示,我的链代码 xml 如下所示。为什么我会得到这个?谁能帮我?

<?xml version="1.0"?>
<opencv_storage>
<chain type_id="opencv-matrix">
  <rows>1</rows>
  <cols>8</cols>
  <dt>f</dt>
  <data>
    5.00000000e-01 0. 0. 0. 5.00000000e-01 0. 0. 0.</data></chain>
</opencv_storage>

错误消息准确无误地说明了问题所在 - 阅读它就足够了。cv::findContours(( 只接受CV_8UC1像素类型的图像,如果使用CV_RETR_FLOODFILL模式,则只接受CV_32SC1。在您的特定情况下,您需要在加载后将 img 对象转换为 CV_8UC1 - 您可能正在加载 RGB 图像。