Как мне максимально точно определить яркую область в изображении?

#python #numpy #image-processing #scikit-image

#python #numpy #обработка изображений #scikit-изображение

Вопрос:

У меня следующая проблема. На изображении ниже показана так называемая каплевидная ДНК. Красным цветом показана трассировка, полученная с помощью skimage.morphology.skeletonize . Ярко-желтая область представляет собой молекулярный комплекс под названием «Стрептавидин», который мне нужно идентифицировать. По сути, моя проблема заключается в двух шагах:

  1. Мне нужно определить самое яркое пятно на изображении. Для этого я применяю к изображению фильтр Гаусса, а затем пробую алгоритм порогового значения (например, skimage.filters.threshold_yen ). Затем я использую skimage.measure.regionprops.centroid для идентификации стрептавидина. Однако этот подход подвержен ошибкам: поскольку мне нужно не только идентифицировать это единственное изображение, но и сделать то же самое для других изображений, я не могу использовать глобальный порог. Для некоторых изображений пороговое значение Yen работает нормально, для некоторых оно вообще не дает результата. Итак, мой вопрос здесь будет следующим: существует ли альтернативный способ определения центроида комплекса стрептавидина, учитывая, что различные изображения отображают разные значения интенсивности, т. Е. Глобальный подход сложно реализовать?
  1. Затем я хочу удалить все точки трассировки (красным цветом), которые находятся внутри комплекса стрептавидина. Здесь я хотел использовать логическую маску, представляющую комплекс стрептавидина, а затем указать программе удалить все точки, которые лежат внутри комплекса. Но опять же, это очень зависит от фактической логической маски, которую я получаю от порогового значения, поэтому я хотел бы подумать о другом способе сделать это.

В целом, вот мой код для справки:

         img_gaussian = filters.gaussian(mol_filtered, sigma=1.)

        # Get threshold (use yen threshold)
        if self.anal_pars['strep_thresh'] is None:
            thresh = filters.threshold_yen(img_gaussian)
            
            # If Yen thresholding fails:
            if thresh < 0.8:
                thresh = filters.threshold_minimum(img_gaussian)
        else:
            thresh = self.anal_pars['strep_thresh']
        
        # Split the image according to threshold selected
        img_bw = copy.deepcopy(img_gaussian)
        img_bw[img_bw < thresh] = 0
        img_bw[img_bw != 0] = 1
         
        # Label the regions that lie above the threshold
        img_labelled = morphology.label(img_bw)
        
        # Check if the thresholding yielded more than one area:
        if img_labelled.max() != 1:
            
             # Remove possible artefacts (happens for Yen filter)
             img_bw = morphology.remove_small_objects(img_bw.astype(bool))
             img_labelled = morphology.label(img_bw) # relabel image
        
        for region in measure.regionprops(img_labelled):
            strep_index = region.centroid
            mol_pars['strep_index'] = strep_index
        
        # Add the streptavidin area to the mol_pars dictionary
        img_strep = copy.deepcopy(img_bw)
        mol_pars['img_strep'] = img_strep
 

Так что это кажется довольно грязным и неэффективным, наверняка есть более быстрый способ сделать это?
Спасибо за вашу помощьИзображение. Желтая яркая область соответствует комплексу стрептавидина. Исходное, нефильтрованное изображение.

Комментарии:

1. Просто запустите простой фильтр Гаусса и пороговое значение. У вас достаточно snr. Может быть, просто пороговое значение непосредственно из гистограммы.

2. Вы поделились изображением своего изображения с осями, аннотациями и, предположительно, цветовой картой, что прекрасно и хорошо, но не могли бы вы дополнительно предоставить чистое, неназванное (предположительно, в оттенках серого) изображение, пожалуйста?

3. Хм, я уже применил фильтр Гаусса и попробовал пороговое значение. Однако иногда это не дает результата, особенно для изображений, где интенсивности выровнены не так четко.

4. Например, когда я делаю то, что предложил @MadPhysicist, центр тяжести находится не точно в середине яркой области, по крайней мере, я бы сделал это из изображения.

5. Вам нужна только точка без цепочки? В этом случае используется медианный фильтр для удаления шума при съемке, вычитание большой медианы для удаления неровностей фона, затем ядро Гаусса, чтобы сделать пик более заметным. Найдите максимальное значение изображения и выполните 2D-подгонку по гауссу в этой области. Установите что-либо около 3-сигма равным нулю. Я опубликую пример numpy scipy, если ни у кого другого не будет ответа к понедельнику.