class TestContentAnalysis(unittest.TestCase):
    def setUp(self):
        self.ca = ContentAnalysis()

    def test_2_lines_are_detected_in_pattern(self):
        img = Image.open(os.path.join(settings.BASE_DIR, 'unit_test/broken_tests/test_data/mul01.jpg'))
        buf = 10  # buffer to include edge
        box = anly.BoxBorder(left=480-buf, upper=0, right=560+buf, lower=1920)

        # each line has 2 elements(rho and theta)
        print( self.ca.lines_detection(img, box) )
        assert self.ca.lines_detection(img, box).size == 4

    def test_2_horizontal_lines_are_detected_in_pattern(self):
        img = Image.open(os.path.join(settings.BASE_DIR, 'unit_test/broken_tests/test_data/mul01.jpg'))
        buf = 10  # buffer to include edge
        h_box = anly.BoxBorder(left=0, upper=480-buf, right=2560, lower=560+buf)
        ca = ContentAnalysis()
        with patch.object(ca, 'lines_detection', return_value=np.array([[[10., 1.57]], [[55., 1.57]]])):
            got_2_lines = ca.count_horizontal_lines(h_box, 2, img)

        assert got_2_lines == True

    def test_2_vertical_lines_are_detected_in_pattern(self):
        img = Image.open(os.path.join(settings.BASE_DIR, 'unit_test/broken_tests/test_data/mul01.jpg'))
        buf = 10  # buffer to include edge
        v_box = anly.BoxBorder(left=480-buf, upper=0, right=560+buf, lower=1920)
        ca = ContentAnalysis()
        with patch.object(ca, 'lines_detection', return_value=np.array([[[10., 0.]], [[55., 0.]]])):
            got_2_lines = self.ca.count_vertical_lines(v_box, 2, img)

        assert got_2_lines == True
    
    def test_2_vertical_lines_are_not_detected_in_pattern(self):
        img = Image.open(os.path.join(settings.BASE_DIR, 'unit_test/broken_tests/test_data/mul95.jpg'))
        buf = 10  # buffer to include edge
        v_box = anly.BoxBorder(left=360-buf, upper=0, right=430+buf, lower=1080)
        ca = ContentAnalysis()
        got_2_lines = self.ca.count_vertical_lines(v_box, 2, img)
        
        assert got_2_lines == False

    def test_check_no_broken_pixel_inside_pattern(self):
        box = anly.BoxBorder(left=480, upper=0, right=560, lower=1920)
        # box = anly.BoxBorder(left=384, upper=0, right=448, lower=1536)
        images = ['unit_test/broken_tests/test_data/mul01.jpg', 'unit_test/broken_tests/test_data/mul02.jpg']

        for image in images:
            image = Image.open(os.path.join(settings.BASE_DIR, image))
            result = self.ca.check_no_broken_pixel(box , image)
            assert result == True

    def test_check_has_broken_pixels_inside_pattern(self):
        vbox = anly.BoxBorder(left=364, upper=0, right=414, lower=1080)
        images = ['unit_test/broken_tests/test_data/mul91.jpg', 'unit_test/broken_tests/test_data/mul92.jpg',
            'unit_test/broken_tests/test_data/mul93.jpg', 'unit_test/broken_tests/test_data/mul94.jpg',
            'unit_test/broken_tests/test_data/mul97.jpg']

        for image in images:
            image = Image.open(os.path.join(settings.BASE_DIR, image))
            result = self.ca.check_no_broken_pixel(vbox , image)
            assert result == False
        
        hbox = anly.BoxBorder(left=0, upper=273, right=1920, lower=313)
        images = [ 'unit_test/broken_tests/test_data/mul96.jpg' ]

        for image in images:
            image = Image.open(os.path.join(settings.BASE_DIR, image))
            result = self.ca.check_no_broken_pixel(hbox , image)
            assert result == False

    def test_cut_to_frames(self):
        self.ca.cut_to_frames(
            os.path.join(settings.BASE_DIR, 'unit_test/broken_tests/test_data/test02.mp4'),
            os.path.join(settings.BASE_DIR, 'unit_test/broken_tests/export'))

        assert os.path.isfile(os.path.join(settings.BASE_DIR, 'unit_test/broken_tests/export/mul00001.jpg'))
        shutil.rmtree(os.path.join(settings.BASE_DIR, 'unit_test/broken_tests/export/'))

    def test_trans_from_points_to_box(self):
        points = [480, 0, 560, 0, 560, 1919, 480, 1919]
        box = self.ca.trans_from_points_to_box(points)

        self.assertEqual(box, anly.BoxBorder(480, 0, 560, 1920))


    # def test_check_video_frames_as_usual_v2(self):
    #     privacy_mask_list = [ 
    #         anly.BoxBorder(left=384, upper=0, right=447, lower=1535),
    #         anly.BoxBorder(left=0, upper=1086, right=2047, lower=1153),
    #         anly.BoxBorder(left=0, upper=384, right=2047, lower=447),
    #         anly.BoxBorder(left=1598, upper=0, right=1665, lower=1535) ]
         
    #     is_usual = self.ca.check_video_frames_as_usual_v2(
    #         os.path.join( os.path.dirname( os.path.realpath( __file__ ) ), 'unittest/medium_stress' ),
    #         privacy_mask_list )
        
    #     self.assertEqual( is_usual, '{"message": "-", "analysis_result": "passed"}' )
    
    # def test_check_video_frames_as_usual_v3(self):
    #     privacy_mask_list = [ 
    #         anly.BoxBorder(left=384, upper=0, right=447, lower=1535),
    #         anly.BoxBorder(left=0, upper=1086, right=2047, lower=1153),
    #         anly.BoxBorder(left=0, upper=384, right=2047, lower=447),
    #         anly.BoxBorder(left=1598, upper=0, right=1665, lower=1535) ]
         
    #     result = self.ca.check_video_frames_as_usual_v3(
    #         os.path.join( os.path.dirname( os.path.realpath( __file__ ) ), 'unittest/medium_stress' ),
    #         privacy_mask_list
    #     )

    #     self.assertEqual( result, { 'result': 'passed', 'failed_frames': [] } )

    def test_check_video_frames_as_usual_v4(self):
        privacy_mask_list = [ 
            anly.BoxBorder(left=384, upper=0, right=447, lower=1535),
            anly.BoxBorder(left=0, upper=1086, right=2047, lower=1153),
            anly.BoxBorder(left=0, upper=384, right=2047, lower=447),
            anly.BoxBorder(left=1598, upper=0, right=1665, lower=1535) ]
        
        # Copy testing frames to dest
        jpg_files = ['seq1.jpg', 'seq2.jpg', 'seq3.jpg', 'seq4.jpg']
        tested_frames = map(lambda x: os.path.join( settings.BASE_DIR, 'unit_test/broken_tests/test_data', x), jpg_files)
        if not os.path.isdir(os.path.join( settings.BASE_DIR, 'unit_test/broken_tests/test_data/seq_frames' )):
            os.makedirs(os.path.join( settings.BASE_DIR, 'unit_test/broken_tests/test_data/seq_frames' ))
        for filename in tested_frames:
            shutil.copy(filename, os.path.join( settings.BASE_DIR, 'unit_test/broken_tests/test_data/seq_frames' ))
        # Start check
        result = self.ca.check_video_frames_as_usual_v4(
            os.path.join( settings.BASE_DIR, 'unit_test/broken_tests/test_data/seq_frames' ),
            privacy_mask_list
        )

        self.assertEqual( result, { 'result': 'passed', 'failed_frames': [] } )

    # def test_save_snapshot_to_dir(self):
    #     framesFolderPath = '/home/dqa/data/pretests'
    #     roi = RoiModule('172.19.16.124', 'root', '', 'NAS')
    #     streamId = roi.get_recording_source()
    #     snapshot_path = self.ca('172.19.16.124', 'root', '').save_snapshot_to_dir(framesFolderPath, streamId)   
        
    #     self.assertEqual(
    #         os.path.exists(snapshot_path),
    #         True
    #     )
    #     self.assertGreater(
    #         os.path.getsize(snapshot_path),
    #         0
    #     )

    def tearDown(self):
        pass
Пример #2
0
def detect_broken_image(pk):

    print("pk= ", pk)
    # filter clip object by id
    clip = ClipInfo.objects.get(id=pk)
    camera = clip.camera_profile
    nas = clip.nas_profile
    # temporary replace without saving
    nas.location = os.path.join(os.path.dirname(clip.full_path), '') if nas.project_profile.type == 'medium' else nas.location
    print("rename nas location= ", nas.location)
    # detect broken
    anly = ContentAnalysis()
    #   1. mount folder
    local_path = os.path.join("/mnt/", nas.location.replace('//', '').replace('/', '_'))
    is_mounted = anly.mount_folder(
        nas.user,
        nas.password,
        nas.location,
        '',
        local_path)
    print("local path= ", local_path)
    print("is_mounted= ", is_mounted)
    clippath = os.path.join(local_path, clip.full_path.lower()[len(nas.location):])
    # framefolder = os.path.join(os.path.dirname(clippath), 'broken', os.path.splitext(os.path.basename(clippath))[0])
    # framefolder = os.path.join(os.path.dirname(clippath), 'broken', '_'.join([os.path.splitext(os.path.basename(clippath))[0], str(time.time())]))
    # [TODO]
    subfolder_with_clipname = clip.full_path.lower()[len(nas.location):].replace('/', '_')
    framefolder = os.path.join('/home/dqa/data/clip2frames', 'camera{}'.format(camera.id), '_'.join([os.path.splitext(subfolder_with_clipname)[0], str(time.time())]))
    # framefolder = os.path.join('/home/dqa/data/clip2frames', 'camera{}'.format(camera.id), '_'.join([os.path.splitext(os.path.basename(clippath))[0], str(time.time())]))

    print("clippath= ", clippath)
    print("framefolder= ", framefolder)
    #   2. cut to frames
    anly.cut_to_frames(
        clippath,
        framefolder
    )
    #   3. check broken
    print("clipprivacy= ", clip.privacy_masks)
    privacy_mask_list = list(map(anly.trans_from_points_to_box, eval(clip.privacy_masks).values()))
    print("privacy_mask_list= ", privacy_mask_list)
    # names_to_corners = eval(clip.privacy_masks)
    # privacy_mask_list = [ 
    #     anly.trans_from_points_to_box(names_to_corners['mask_up']),
    #     anly.trans_from_points_to_box(names_to_corners['mask_down']),
    #     anly.trans_from_points_to_box(names_to_corners['mask_left']),
    #     anly.trans_from_points_to_box(names_to_corners['mask_right']) ]

    video_status = anly.check_video_frames_as_usual_v4(
        framefolder,
        privacy_mask_list
    )
    print("video_status: ", video_status)
    # # create brokenInfo
    # ex: video_status = {
    #     'result': 'failed',
    #     'failed_frames': [
    #         {
    #             'error_message': "decoede error",
    #             'path': "a/b/c.mp4"
    #         },
    #         {
    #             'error_message': "decoede error",
    #             'path': "a/b/c.mp4"
    #         },
    #     ] }
    BrokenFrameHelper(clip.id).batch_create_db(video_status)

    # for failed_frame in video_status['failed_frames']:
    #     print("each failed frame: ", failed_frame)
    #     m = re.search(r"mul(?P<timestamp>[0-9]+).jpg", failed_frame['path'])
    #     if m:
    #         seq_to_seconds = round(int(m.group('timestamp'))/2, 1) # 2: fps
    #         timestamp = datetime.timedelta(seconds=seq_to_seconds)
    #         # replace broken frame path with timestamp
    #         renamed_path = failed_frame['path'].replace(
    #             'mul'+m.group('timestamp'),
    #             str(timestamp).replace(":", "'")
    #         )
    #         os.rename(failed_frame['path'], renamed_path)
    #         failed_frame['path'] = renamed_path
    #     else:
    #         timestamp = None

    #     BrokenFrame.objects.create(
    #         error_message=failed_frame['error_message'],
    #         frame_path=failed_frame['path'],
    #         clip=clip,
    #         timestamp=timestamp
    #     )

    print( "video_status: ", video_status )
    # copy framefolder's jpgs to clipath folder
    remote_framefolder_name = os.path.splitext(os.path.basename(clip.full_path))[0]
    print( "remote_framefolder_name: ", remote_framefolder_name)
    mount_point_2_remote_framefolder_path = os.path.join(os.path.dirname(clippath), 'broken', os.path.basename(remote_framefolder_name))
    print( "mount_point_2_remote_framefolder_path: ", mount_point_2_remote_framefolder_path)
    if os.path.exists(mount_point_2_remote_framefolder_path):
        shutil.rmtree(mount_point_2_remote_framefolder_path)
    shutil.copytree(framefolder, mount_point_2_remote_framefolder_path)

    # shutil.copytree(framefolder, os.path.join(os.path.dirname(clippath), 'broken', os.path.basename(framefolder)))
    # update analysis info
    clip.size = os.path.getsize(clippath)
    clip.is_broken = False if video_status['result'] == 'passed' else True
    clip.creation_time = datetime.datetime.fromtimestamp(os.stat(clippath).st_mtime)
    clip.save()