如何从此X射线图像中删除水平线?

时间:2016-05-25 19:19:44

标签: c++ visual-studio opencv

我是opencv(c ++)的新手,我想从这个X射线图像中删除水平线。但我不能。

这是我的形象:

enter image description here

您建议如何解决此任务的想法?或者我可以在互联网上的哪些资源上找到帮助?

这是我的c ++代码

src = imread("C:/Users/Alireza/Desktop/New folder (3)/11.bmp");
cvtColor(src, gray, CV_RGB2GRAY);
imshow("Original Image", gray);
imwrite("Original Image.png", gray);
normalize(gray, gray, 0, 250, NORM_MINMAX, -1, Mat());
threshold(gray, thresh, 170, 255, THRESH_BINARY_INV);
vector< vector <Point> > contours;        
vector< Vec4i > hierarchy;
int largest_contour_index = 0;
int largest_area = 0;
Mat alpha(src.size(), CV_8UC1, Scalar(0));
findContours(thresh, contours, hierarchy, CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
for (int i = 0; i< contours.size(); i++)                                
{
double a = contourArea(contours[i], false); 
if (a>largest_area)
{
largest_area = a;
largest_contour_index =     i;                                                                
}
}
drawContours(alpha, contours,     largest_contour_index,Scalar(255),CV_FILLED, 8, hierarchy);         
vector<Mat> rgb;
split(src, rgb);
Mat rgba[4] = { rgb[0], rgb[1], rgb[2], alpha };
merge(rgba, 4, Tafrigh);
imshow("Tafrigh", Tafrigh);
imwrite("Tafrigh.png", Tafrigh);

2 个答案:

答案 0 :(得分:2)

进行2D FFT,看一下光谱。您将看到沿中心y轴的大量点。抑制那些点,反向变换,你的垂直线将消失。

在Python的结果下面(因为我没有安装C ++和opencv),使用滑块来改变要抑制的区域。考虑它Pseudocode。这仍然相当粗糙,因为为了简单起见,我没有在这里对抑制像素及其邻居进行平滑过渡。

%matplotlib inline
from __future__ import division
import numpy as np
import matplotlib.pyplot as p
from ipywidgets import *

from scipy import misc
f = misc.imread('xray_image_with_horizontal_lines.png')

a=np.fft.fftshift(np.fft.fft2(f)) 

def process(kx,ky):
    p.figure(figsize=(12,8))
    p.subplot(221)
    p.imshow(f, cmap=p.cm.gray)
    p.subplot(222)
    p.imshow(np.abs(np.log(a)), cmap=p.cm.gray)

    print np.shape(a)
    b=np.zeros_like(a)
    for i in range(639):
        for j in range(406):
            if not ( 320-kx<i<320+kx and (j<203-ky or j>203+ky)):
                b[j,i]=a[j,i]

    c=np.fft.ifft2(b)
    p.subplot(223)
    p.imshow(np.abs(np.log(b)), cmap=p.cm.gray)
    p.subplot(224)
    p.imshow(np.abs(c), cmap=p.cm.gray)  

interact(process, kx=[1,20,1],ky=[1,20,1])

enter image description here

答案 1 :(得分:1)

这只是一个想法:保持平均线不变。

cv::Mat image = cv::imread("Tf6HO.png",CV_LOAD_IMAGE_GRAYSCALE);
vector<double> moyenne;
double minval,maxval;
minMaxLoc(image,&minval,&maxval);
imshow("original",image);
for (int i = 0; i < image.rows; i++)
{
    double s=0;
// Caluclate mean for row i
    for (int j=0;j<image.cols;j++)
        s += image.at<uchar>(i,j);
// Store result in vector moyenne
    moyenne.push_back(s/image.cols);
}
// Energy for row i equal to a weighted mean of row in [i-nbInf,i+nbSup]
int nbInf=32,nbSup=0;
for (int i = 0; i < image.rows; i++)
{
    double s=0,p=0;
    // weighted mean (border effect process with max and min method
    for (int j = max(0, i - nbInf); j <= min(image.rows - 1, i + nbSup); j++)
    {
        s+=moyenne[j]*1./(1+abs(i-j));
        p+=1./(1+abs(i-j));
    }
    // Weighted mean
    s/=p;
    // process pixel in row i : mean of row i equal to s 
    for (int j=0;j<image.cols;j++)
        image.at<uchar>(i,j) =saturate_cast<uchar>((image.at<uchar>(i,j)-moyenne[i])+s);
}
imshow("process",image);
waitKey();

result 或降低分辨率 enter image description here

如果您想改进,可以阅读此paper和参考书目