반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

폴크(FOLC)

머신 비전 알고리즘 - OpenCV - 이미지처리29 본문

머신 비전/머신 비전 알고리즘 테크닉 CPP

머신 비전 알고리즘 - OpenCV - 이미지처리29

folcjin 2021. 8. 14. 23:01
728x90
반응형

# 디지털 이미지 처리
   # 이미지의 상태 정보에서 일반적인 정보를 생성한다.
      > 추출된 정보를 일반화한다.

# 이미지 처리 - OpenCV 4.5.3 으로 테스트
   # 이미지의 상태 정보에서 일반적인 정보를 생성
   > Points : 입력, model : 결과, distance : 노이즈로 판단하는 경계값

# RANSAC ( Random sample consensus )
   > vector<cv::Point2f> vecData;
   > CFitLineRANSAC ransac;
   > cv::Vec4f model;
   > ransac.FitLine(vecData, 3.0, model);

 



* 소스 코드 세부 내용 *
double CFitLineRANSAC::FitLine(const vector<cv::Point2f> &src, double distance_threshold, cv::Vec4f &result_model)
{
const int source_count = (int)src.size();
const int sample_count = 2;

if (source_count < sample_count)
{
return 0.0;
}

const int total_iter_count = (int)(1 + log(1.0 - 0.99) / log(1.0 - pow(0.5, sample_count)));

vector<cv::Point2f> vecSamples(sample_count);

double max_cost = 0.0;

for (int i = 0; i < total_iter_count; i++)
{
GetSampleToCompute(src, vecSamples);

cv::Vec4f estimated_model;
ComputeModelParameter(vecSamples, estimated_model);

vector<cv::Point2f> vecInliers;
const double cost = VerificationLineModel(estimated_model, distance_threshold, src, vecInliers);

if (max_cost < cost)
{
max_cost = cost;

ComputeModelParameter(vecInliers, result_model);
}
}

return max_cost;
}

void CFitLineRANSAC::GetSampleToCompute(const vector<cv::Point2f> &src, vector<cv::Point2f> &dst)
{
srand(RAND_MAX);

const int source_count = (int)src.size();

vector<int> vecIndex;

    while(true)
    {
const int random_index = rand() % source_count;

if(find(vecIndex.begin(), vecIndex.end(), random_index) == vecIndex.end())
{
vecIndex.push_back(random_index);
}

if (vecIndex.size() == dst.size())
{
for (size_t i = 0; i < dst.size(); ++i)
{
dst[i] = src[vecIndex[i]];
}

return;
}
}
}

void CFitLineRANSAC::ComputeModelParameter(const vector<cv::Point2f> &src, cv::Vec4f &model)
{
    double sx  = 0, sy  = 0;
    double sxx = 0, syy = 0;
    double sxy = 0, sw  = 0;
    for(size_t i = 0; i < src.size(); ++i)
    {
        const double &x = src[i].x;
        const double &y = src[i].y;

        sx  += x;
        sy  += y;
        sxx += x * x;
        sxy += x * y;
        syy += y * y;
        sw  += 1;
    }

    const double vxx = (sxx - sx * sx / sw) / sw;
    const double vxy = (sxy - sx * sy / sw) / sw;
    const double vyy = (syy - sy * sy / sw) / sw;
    const double theta = atan2(2.0 * vxy, vxx - vyy) / 2.0;

    model[0] = (float)cos(theta);
    model[1] = (float)sin(theta);
    model[2] = (float)(sx / sw);
    model[3] = (float)(sy / sw);
}

double CFitLineRANSAC::ComputeDistancePoint(const cv::Vec4f &line, const cv::Point2f &x)
{
const double det = sqrt(line[0] * line[0] + line[1] * line[1]);

    return fabs((x.x - line[2]) * line[1] - (x.y - line[3]) * line[0]) / det;
}

double CFitLineRANSAC::VerificationLineModel(const cv::Vec4f &estimated_model, const double &distance_threshold, const vector<cv::Point2f> &src, vector<cv::Point2f> &dst)
{
    double cost = 0.0;

    for(size_t i = 0; i < src.size(); i++)
    {
        if (ComputeDistancePoint(estimated_model, src[i]) < distance_threshold)
        {
            cost += 1.0;

dst.push_back(src[i]);
        }
    }

    return cost;
}

728x90
반응형
사업자 정보 표시
사업자 등록번호 : -- | TEL : --